diff --git a/documentation/content/en/articles/committers-guide/_index.adoc b/documentation/content/en/articles/committers-guide/_index.adoc index 7f00f90a62..af20a3aed7 100644 --- a/documentation/content/en/articles/committers-guide/_index.adoc +++ b/documentation/content/en/articles/committers-guide/_index.adoc @@ -1,3870 +1,3870 @@ --- title: Committer's Guide authors: - author: The FreeBSD Documentation Project copyright: 1999-2026 The FreeBSD Documentation Project description: Introductory information for FreeBSD committers trademarks: ["freebsd", "coverity", "git", "github", "gitlab", "ibm", "intel", "general"] weight: 25 tags: ["FreeBSD Committer's Guide", "Guide", "Community"] --- = Committer's Guide :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :source-highlighter: rouge :experimental: :images-path: articles/committers-guide/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Abstract This document provides information for the FreeBSD committer community. All new committers should read this document before they start, and existing committers are strongly encouraged to review it from time to time. Almost all FreeBSD developers have commit rights to one or more repositories. However, a few developers do not, and some of the information here applies to them as well. (For instance, some people only have rights to work with the Problem Report database.) Please see crossref:committers-guide[non-committers, Issues Specific to Developers Who Are Not Committers] for more information. This document may also be of interest to members of the FreeBSD community who want to learn more about how the project works. ''' toc::[] [[admin]] == Administrative Details [.informaltable] [cols="1,1", frame="none"] |=== |_Login Methods_ |man:ssh[1], protocol 2 only |_Main Shell Host_ |`freefall.FreeBSD.org` |_Reference Machines_ |`ref*.FreeBSD.org`, `universe*.freeBSD.org` (see also link:https://www.FreeBSD.org/internal/machines/[FreeBSD Project Hosts]) |_SMTP Host_ |`smtp.FreeBSD.org:587` (see also crossref:committers-guide[smtp-setup, SMTP Access Setup]). |`_src/_` Git Repository |`ssh://git@gitrepo.FreeBSD.org/src.git` |`_doc/_` Git Repository |`ssh://git@gitrepo.FreeBSD.org/doc.git` |`_ports/_` Git Repository |`ssh://git@gitrepo.FreeBSD.org/ports.git` |_Internal Mailing Lists_ |developers (technically called all-developers), doc-developers, doc-committers, ports-developers, ports-committers, src-developers, src-committers. (Each project repository has its own -developers and -committers mailing lists. Archives for these lists can be found in the files [.filename]#/local/mail/repository-name-developers-archive# and [.filename]#/local/mail/repository-name-committers-archive# on `freefall.FreeBSD.org`.) |_Core Team monthly reports_ |[.filename]#/home/core/public/reports# on the `FreeBSD.org` cluster. |_Ports Management Team monthly reports_ |[.filename]#/home/portmgr/public/monthly-reports# on the `FreeBSD.org` cluster. |_Noteworthy `src/` Git Branches:_ |`stable/n` (`n`-STABLE), `main` (-CURRENT) |=== man:ssh[1] is required to connect to the project hosts. For more information, see crossref:committers-guide[ssh.guide, SSH Quick-Start Guide]. Useful links: * link:https://www.FreeBSD.org/internal/[FreeBSD Project Internal Pages] * link:https://www.FreeBSD.org/internal/machines/[FreeBSD Project Hosts] * link:https://www.FreeBSD.org/administration/[FreeBSD Project Administrative Groups] [[pgpkeys]] == OpenPGP Keys for FreeBSD Cryptographic keys conforming to the OpenPGP (__Pretty Good Privacy__) standard are used by the FreeBSD project to authenticate committers. Messages carrying important information like public SSH keys can be signed with the OpenPGP key to prove that they are really from the committer. See https://nostarch.com/releases/pgp_release.pdf[PGP & GPG: Email for the Practical Paranoid by Michael Lucas] and https://en.wikipedia.org/wiki/Pretty_Good_Privacy[] for more information. [[pgpkeys-creating]] === Creating a Key Existing keys can be used, but should be checked with [.filename]#documentation/tools/checkkey.sh# first. In this case, make sure the key has a FreeBSD user ID. For those who do not yet have an OpenPGP key, or need a new key to meet FreeBSD security requirements, here we show how to generate one. [[pgpkeys-create-steps]] [.procedure] ==== . Install [.filename]#security/gnupg#. Enter these lines in [.filename]#~/.gnupg/gpg.conf# to set minimum acceptable defaults for signing and new key preferences (see the link:https://www.gnupg.org/documentation/manuals/gnupg/GPG-Options.html[GnuPG options documentation] for more details): + [.programlisting] .... # Sorted list of preferred algorithms for signing (strongest to weakest). personal-digest-preferences SHA512 SHA384 SHA256 SHA224 # Default preferences for new keys default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 CAMELLIA256 AES192 CAMELLIA192 AES CAMELLIA128 CAST5 BZIP2 ZLIB ZIP Uncompressed .... . Generate a key: + [source,shell] .... % gpg --full-gen-key gpg (GnuPG) 2.1.8; Copyright (C) 2015 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Warning: using insecure memory! Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 2048 <.> Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 3y <.> Key expires at Wed Nov 4 17:20:20 2015 MST Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Chucky Daemon <.> Email address: notreal@example.com Comment: You selected this USER-ID: "Chucky Daemon " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. .... <.> 2048-bit keys with a three-year expiration provide adequate protection at present (2022-10). <.> A three year key lifespan is short enough to obsolete keys weakened by advancing computer power, but long enough to reduce key management problems. <.> Use your real name here, preferably matching that shown on government-issued ID to make it easier for others to verify your identity. Text that may help others identify you can be entered in the `Comment` section. + After the email address is entered, a passphrase is requested. Methods of creating a secure passphrase are contentious. Rather than suggest a single way, here are some links to sites that describe various methods: https://world.std.com/~reinhold/diceware.html[], https://www.iusmentis.com/security/passphrasefaq/[], https://xkcd.com/936/[], https://en.wikipedia.org/wiki/Passphrase[]. ==== Protect the private key and passphrase. If either the private key or passphrase may have been compromised or disclosed, immediately notify mailto:accounts@FreeBSD.org[accounts@FreeBSD.org] and revoke the key. Committing the new key is shown in crossref:committers-guide[commit-steps, Steps for New Committers]. [[kerberos-ldap]] == Kerberos and LDAP web Password for FreeBSD Cluster The FreeBSD cluster requires a Kerberos password to access certain services. The Kerberos password also serves as the LDAP web password, since LDAP is proxying to Kerberos in the cluster. Some of the services which require this include: * https://bugs.freebsd.org/bugzilla[Bugzilla] To create a new Kerberos account in the FreeBSD cluster, or to reset a Kerberos password for an existing account using a random password generator: [source,shell] .... % ssh kpasswd.freebsd.org .... [NOTE] ==== This must be done from a machine outside of the FreeBSD.org cluster. ==== A Kerberos password can also be set manually by logging into `freefall.FreeBSD.org` and running: [source,shell] .... % kpasswd .... [NOTE] ==== Unless the Kerberos-authenticated services of the FreeBSD.org cluster have been used previously, `Client unknown` will be shown. This error means that the `ssh kpasswd.freebsd.org` method shown above must be used first to initialize the Kerberos account. ==== [[committer.types]] == Commit Bit Types The FreeBSD repository has a number of components which, when combined, support the basic operating system source, documentation, third party application ports infrastructure, and various maintained utilities. When FreeBSD commit bits are allocated, the areas of the tree where the bit may be used are specified. Generally, the areas associated with a bit reflect who authorized the allocation of the commit bit. Additional areas of authority may be added at a later date: when this occurs, the committer should follow normal commit bit allocation procedures for that area of the tree, seeking approval from the appropriate entity and possibly getting a mentor for that area for some period of time. [.informaltable] [cols="1,1,1", frame="none"] |=== |__Committer Type__ |__Responsible__ |__Tree Components__ |src |srcmgr@ |src/ |doc |doceng@ |doc/, ports/, src/ documentation |ports |portmgr@ |ports/ |=== Commit bits allocated prior to the development of the notion of areas of authority may be appropriate for use in many parts of the tree. However, common sense dictates that a committer who has not previously worked in an area of the tree seek review prior to committing, seek approval from the appropriate responsible party, and/or work with a mentor. Since the rules regarding code maintenance differ by area of the tree, this is as much for the benefit of the committer working in an area of less familiarity as it is for others working on the tree. Committers are encouraged to seek review for their work as part of the normal development process, regardless of the area of the tree where the work is occurring. === Policy for Committer Activity in Other Trees Committers are trusted to use good judgment when working outside their primary area. The link:https://www.freebsd.org/internal/cross-repo-commits/[Cross Repo Commit Policy] describes the overall framework. The following guidelines apply: ==== General Guidelines These changes do not require review or approval from a committer in the target repository: * All committers may modify [.filename]#src/share/misc/committers-*.dot#, [.filename]#src/usr.bin/calendar/calendars/calendar.freebsd#, and [.filename]#ports/astro/xearth/files#. * All committers may commit documentation changes to [.filename]#src# files, such as manual pages, READMEs, fortune databases, calendar files, and comment fixes, subject to the normal care and tending of commits. * Obvious trivial fixes — typos, broken links, and similar trivial corrections — may be committed by any committer to any repository (see also <>). * When you have recently introduced a build breakage that's trivial to resolve, though a revert and a full review usually is better for anything non-trivial. ==== Non-Obvious Changes For changes beyond those described here, committers should seek review from committers with the appropriate bit in the target repository. When in doubt, seek review, even if you have a commit bit in the repo. Always test build and test run or read files affected by the change. ==== Acquiring Additional Commit Bits Committers can acquire an additional bit by the usual process of finding a mentor who will propose them to srcmgr, doceng, or portmgr, as appropriate. [[doc-blanket-approval]] ==== Documentation Implicit (Blanket) Approval Some types of fixes have "blanket approval" from the {doceng}, allowing any committer to fix those categories of problems on any part of the doc tree. These fixes do not need approval or review from a doc committer if the author doesn't have a doc commit bit. Blanket approval applies to these types of fixes: * Typos * Trivial fixes + Punctuation, URLs, dates, paths and file names with outdated or incorrect information, and other common mistakes that may confound the readers. Over the years, some implicit approvals were granted in the doc tree. This list shows the most common cases: * Changes in [.filename]#documentation/content/en/books/porters-handbook/versions/_index.adoc# + extref:{porters-handbook}versions/[__FreeBSD_version Values (Porter's Handbook)], mainly used for src committers. * Changes in [.filename]#doc/shared/contrib-additional.adoc# + extref:{contributors}[Additional FreeBSD Contributors, contrib-additional] maintenance. * All link:#commit-steps[Steps for New Committers], doc related * Security advisories; Errata Notices; Releases; + Used by {security-officer} and {re}. * Changes in [.filename]#website/content/en/donations/donors.adoc# + Used by {donations}. Before any commit, a build test is necessary; see the 'Overview' and 'The FreeBSD Documentation Build Process' sections of the extref:{fdp-primer}[FreeBSD Documentation Project Primer for New Contributors] for more details. [[git-primer]] == Git Primer [[git-basics]] === Git basics When one searches for "Git Primer" a number of good ones come up. Daniel Miessler's link:https://danielmiessler.com/study/git/[A git primer] and Willie Willus' link:https://gist.github.com/williewillus/068e9a8543de3a7ef80adb2938657b6b[Git - Quick Primer] are both good overviews. The Git book is also complete, but much longer https://git-scm.com/book/en/v2. There is also this website https://dangitgit.com/ for common traps and pitfalls of Git, in case you need guidance to fix things up. Finally, an introduction link:https://eagain.net/articles/git-for-computer-scientists/[targeted at computer scientists] has proven helpful to some at explaining the Git world view. This document will assume that you've read through it and will try not to belabor the basics (though it will cover them briefly). [[git-mini-primer]] === Git Mini Primer This primer is less ambitiously scoped than the old Subversion Primer, but should cover the basics. ==== Scope If you want to download FreeBSD, compile it from sources, and generally keep up to date that way, this primer is for you. It covers getting the sources, updating the sources, bisecting and touches briefly on how to cope with a few local changes. It covers the basics, and tries to give good pointers to more in-depth treatment for when the reader finds the basics insufficient. Other sections of this guide cover more advanced topics related to contributing to the project. The goal of this section is to highlight those bits of Git needed to track sources. They assume a basic understanding of Git. There are many primers for Git on the web, but the https://git-scm.com/book/en/v2[Git Book] provides one of the better treatments. [[git-mini-primer-getting-started]] ==== Getting Started For Developers This section describes the read-write access for committers to push the commits from developers or contributors. [[git-mini-daily-use]] ===== Daily use [NOTE] ==== In the examples below, replace `${repo}` with the name of the desired FreeBSD repository: `doc`, `ports`, or `src`. ==== * Clone the repository: + [source,shell] .... % git clone -o freebsd --config remote.freebsd.fetch='+refs/notes/*:refs/notes/*' https://git.freebsd.org/${repo}.git .... + Then you should have the official mirrors as your remote: + [source,shell] .... % git remote -v freebsd https://git.freebsd.org/${repo}.git (fetch) freebsd https://git.freebsd.org/${repo}.git (push) .... * Configure the FreeBSD committer data: + The commit hook in repo.freebsd.org checks the "Commit" field matches the committer's information in FreeBSD.org. The easiest way to get the suggested config is by executing `/usr/local/bin/gen-gitconfig.sh` script on freefall: + [source,shell] .... % gen-gitconfig.sh [...] % git config user.name (your name in gecos) % git config user.email (your login)@FreeBSD.org .... * Set the push URL: + [source,shell] .... % git remote set-url --push freebsd git@gitrepo.freebsd.org:${repo}.git .... + Then you should have separated fetch and push URLs as the most efficient setup: + [source,shell] .... % git remote -v freebsd https://git.freebsd.org/${repo}.git (fetch) freebsd git@gitrepo.freebsd.org:${repo}.git (push) .... + Again, note that `gitrepo.freebsd.org` has been canonicalized to `repo.freebsd.org`. * Install commit message template hook: + For doc repository: + [source,shell] .... % cd .git/hooks % ln -s ../../.hooks/prepare-commit-msg .... + For ports repository: + [source,shell] .... % git config --add core.hooksPath .hooks .... + For src repository: + [source,shell] .... % cd .git/hooks % ln -s ../../tools/tools/git/hooks/prepare-commit-msg .... [[admin-branch]] ===== "admin" branch The `access` and `mentors` files are stored in an orphan branch, `internal/admin`, in each repository. Following example is how to check out the `internal/admin` branch to a local branch named `admin`: [source,shell] .... % git config --add remote.freebsd.fetch '+refs/internal/*:refs/internal/*' % git fetch % git checkout -b admin internal/admin .... Alternatively, you can add a worktree for the `admin` branch: [source,shell] .... git worktree add -b admin ../${repo}-admin internal/admin .... For browsing `internal/admin` branch on web: -`https://cgit.freebsd.org/${repo}/log/?h=internal/admin` +`pass:macros[https://cgit.freebsd.org/${repo}/log/?h=internal/admin]` For pushing, specify the full refspec: [source,shell] .... git push freebsd HEAD:refs/internal/admin .... ==== Keeping Current With The FreeBSD src Tree [[keeping_current]] First step: cloning a tree. This downloads the entire tree. There are two ways to download. Most people will want to do a deep clone of the repository. However, there are times when you may wish to do a shallow clone. ===== Branch Names FreeBSD-CURRENT uses the `main` branch. `main` is the default branch. For FreeBSD-STABLE, branch names include `stable/{rel-latest-major}` and `stable/{rel-legacy-major}`. For FreeBSD-RELEASE, release engineering branch names include `releng/{rel-latest}` and `releng/{rel-legacy}`. https://www.freebsd.org/releng/[] shows: * `main` and `stable/⋯` branches open * `releng/⋯` branches, each of which is frozen when a release is tagged. Examples: * tag https://cgit.freebsd.org/src/tag/?h=release/{rel-latest}.0[release/{rel-latest}.0] on the https://cgit.freebsd.org/src/log/?h=releng/{rel-latest}[releng/{rel-latest}] branch * tag https://cgit.freebsd.org/src/tag/?h=release/{rel-legacy}.0[release/{rel-legacy}.0] on the https://cgit.freebsd.org/src/log/?h=releng/{rel-legacy}[releng/{rel-legacy}] branch. ===== Repositories Please see the crossref:committers-guide[admin,Administrative Details] for the latest information on where to get FreeBSD sources. $URL below can be obtained from that page. Note: The project doesn't use submodules as they are a poor fit for our workflows and development model. How we track changes in third-party applications is discussed elsewhere and generally of little concern to the casual user. ===== Deep Clone A deep clone pulls in the entire tree, as well as all the history and branches. It is the easiest to do. It also allows you to use Git's worktree feature to have all your active branches checked out into separate directories but with only one copy of the repository. [source,shell] .... % git clone -o freebsd $URL -b branch [] .... -- will create a deep clone. `branch` should be one of the branches listed in the previous section. If no `branch` is given: the default (`main`) will be used. If no `` is given: the name of the new directory will match the name of the repo ([.filename]#doc#, [.filename]#ports# or [.filename]#src#). You will want a deep clone if you are interested in the history, plan on making local changes, or plan on working on more than one branch. It is the easiest to keep up to date as well. If you are interested in the history, but are working with only one branch and are short on space, you can also use --single-branch to only download the one branch (though some merge commits will not reference the merged-from branch which may be important for some users who are interested in detailed versions of history). ===== Shallow Clone A shallow clone copies just the most current code, but none or little of the history. This can be useful when you need to build a specific revision of FreeBSD, or when you are just starting out and plan to track the tree more fully. You can also use it to limit history to only so many revisions. However, see below for a significant limitation of this approach. [source,shell] .... % git clone -o freebsd -b branch --depth 1 $URL [dir] .... This clones the repository, but only has the most recent version in the repository. The rest of the history is not downloaded. Should you change your mind later, you can do `git fetch --unshallow` to get the old history. [WARNING] ==== When you make a shallow clone, you will lose the commit count in your uname output. This can make it more difficult to determine if your system needs to be updated when a security advisory is issued. ==== ===== Building Once you've downloaded, building is done as described in the handbook, e.g.: [source,shell] .... % cd src % make buildworld % make buildkernel % make installkernel % make installworld .... so that won't be covered in depth here. If you want to build a custom kernel, extref:{handbook}kernelconfig[the kernel config section, kernelconfig] of the FreeBSD Handbook recommends creating a file MYKERNEL under sys/${ARCH}/conf with your changes against GENERIC. To have MYKERNEL disregarded by Git, it can be added to .git/info/exclude. ===== Updating To update both types of trees uses the same commands. This pulls in all the revisions since your last update. [source,shell] .... % git pull --ff-only .... will update the tree. In Git, a 'fast forward' merge is one that only needs to set a new branch pointer and doesn't need to re-create the commits. By always doing a fast forward merge/pull, you'll ensure that you have an exact copy of the FreeBSD tree. This will be important if you want to maintain local patches. See below for how to manage local changes. The simplest is to use `--autostash` on the `git pull` command, but more sophisticated options are available. ==== Selecting a Specific Version In Git, `git checkout` checks out both branches and specific versions. Git's versions are the long hashes rather than a sequential number. When you checkout a specific version, just specify the hash you want on the command line (the git log command can help you decide which hash you might want): [source,shell] .... % git checkout 08b8197a74 .... and you have that checked out. You will be greeted with a message similar to the following: [source,shell] .... Note: checking out '08b8197a742a96964d2924391bf9fdfeb788865d'. You are in a 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b HEAD is now at 08b8197a742a hook gpiokeys.4 to the build .... where the last line is generated from the hash you are checking out and the first line of the commit message from that revision. The hash can be abbreviated to the shortest unique length. Git itself is inconsistent about how many digits it displays. ==== Bisecting Sometimes, things go wrong. The last version worked, but the one you just updated to does not. A developer may ask you to bisect the problem to track down which commit caused the regression. Git makes bisecting changes easy with a powerful `git bisect` command. Here's a brief outline of how to use it. For more information, you can view https://www.metaltoad.com/blog/beginners-guide-git-bisect-process-elimination or https://git-scm.com/docs/git-bisect for more details. The man git-bisect page is good at describing what can go wrong, what to do when versions won't build, when you want to use terms other than 'good' and 'bad', etc, none of which will be covered here. `git bisect start --first-parent` will start the bisection process. Next, you need to tell a range to go through. `git bisect good XXXXXX` will tell it the working version and `git bisect bad XXXXX` will tell it the bad version. The bad version will almost always be HEAD (a special tag for what you have checked out). The good version will be the last one you checked out. The `--first-parent` argument is necessary so that subsequent `git bisect` commands do not try to check out a vendor branch which lacks the full FreeBSD source tree. [TIP] ==== If you want to know the last version you checked out, you should use `git reflog`: [source,shell] .... 5ef0bd68b515 (HEAD -> main, freebsd/main, freebsd/HEAD) HEAD@{0}: pull --ff-only: Fast-forward a8163e165c5b (upstream/main) HEAD@{1}: checkout: moving from b6fb97efb682994f59b21fe4efb3fcfc0e5b9eeb to main ... .... shows me moving the working tree to the `main` branch (a816...) and then updating from upstream (to 5ef0...). In this case, bad would be HEAD (or 5ef0bd68b515) and good would be a8163e165c5b. As you can see from the output, HEAD@{1} also often works, but isn't foolproof if you have done other things to your Git tree after updating, but before you discover the need to bisect. ==== Set the 'good' version first, then set the bad (though the order doesn't matter). When you set the bad version, it will give you some statistics on the process: [source,shell] .... % git bisect start --first-parent % git bisect good a8163e165c5b % git bisect bad HEAD Bisecting: 1722 revisions left to test after this (roughly 11 steps) [c427b3158fd8225f6afc09e7e6f62326f9e4de7e] Fixup r361997 by balancing parens. Duh. .... You would then build/install that version. If it's good you'd type `git bisect good` otherwise `git bisect bad`. If the version doesn't compile, type `git bisect skip`. You will get a similar message to the above after each step. When you are done, report the bad version to the developer (or fix the bug yourself and send a patch). `git bisect reset` will end the process and return you back to where you started (usually tip of `main`). Again, the git-bisect manual (linked above) is a good resource for when things go wrong or for unusual cases. [[git-gpg-signing]] ==== Signing the commits, tags, and pushes, with GnuPG Git knows how to sign commits, tags, and pushes. When you sign a Git commit or a tag, you can prove that the code you submitted came from you and wasn't altered while you were transferring it. You also can prove that you submitted the code and not someone else. A more in-depth documentation on signing commits and tags can be found in the https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work[Git Tools - Signing Your Work] chapter of the Git's book. The rationale behind signing pushes can be found in the https://github.com/git/git/commit/a85b377d0419a9dfaca8af2320cc33b051cbed04[commit that introduced the feature]. The best way is to simply tell Git you always want to sign commits, tags, and pushes. You can do this by setting a few configuration variables: [source,shell] .... % git config --add user.signingKey LONG-KEY-ID % git config --add commit.gpgSign true % git config --add tag.gpgSign true % git config --add push.gpgSign if-asked .... // push.gpgSign should probably be set to `yes` once we enable it, or be set with --global, so that it is enabled for all repositories. [NOTE] ====== To avoid possible collisions, make sure you give a long key id to Git. You can get the long id with: `gpg --list-secret-keys --keyid-format LONG`. ====== [TIP] ====== To use specific subkeys, and not have GnuPG to resolve the subkey to a primary key, attach `!` to the key. For example, to encrypt for the subkey `DEADBEEF`, use `DEADBEEF!`. ====== ===== Verifying signatures Commit signatures can be verified by running either `git verify-commit `, or `git log --show-signature`. Tag signatures can be verified with `git verify-tag `, or `git tag -v `. //// Commented out for now until we decide what to do. Git pushes are a bit different, they live in a special ref in the repository. TODO: write how to verify them //// ==== Ports Considerations The ports tree operates the same way. The branch names are different and the repositories are in different locations. The cgit repository web interface for use with web browsers is at https://cgit.FreeBSD.org/ports/ . The production Git repository is at https://git.FreeBSD.org/ports.git and at ssh://anongit@git.FreeBSD.org/ports.git (or `anongit@git.FreeBSD.org:ports.git`). There is also a mirror on GitHub, see extref:{handbook}mirrors[External mirrors, mirrors] for an overview. The _latest_ branch is `main`. The _quarterly_ branches are named `yyyyQn` for year 'yyyy' and quarter 'n'. [[port-commit-message-formats]] ===== Commit message formats A hook is available in the ports repository to help you write up your commit messages in https://cgit.freebsd.org/ports/tree/.hooks/prepare-commit-msg[.hooks/prepare-commit-message]. It can be enabled by running ``git config --add core.hooksPath .hooks``. The main point being that a commit message should be formatted in the following way: .... category/port: Summary. Description of why the changes where made. PR: 12345 .... [IMPORTANT] ==== The first line is the subject of the commit, it contains what port was changed, and a summary of the commit. It should contain 50 characters or less. A blank line should separate it from the rest of the commit message. The rest of the commit message should be wrapped at the 72 characters boundary. Another blank line should be added if there are any metadata fields, so that they are easily distinguishable from the commit message. ==== ==== Managing Local Changes This section addresses tracking local changes. If you have no local changes you can skip this section. One item that is important for all of them: all changes are local until pushed. Unlike Subversion, Git uses a distributed model. For users, for most things, there is very little difference. However, if you have local changes, you can use the same tool to manage them as you use to pull in changes from FreeBSD. All changes that you have not pushed are local and can easily be modified (git rebase, discussed below does this). ===== Keeping local changes The simplest way to keep local changes (especially trivial ones) is to use `git stash`. In its simplest form, you use `git stash` to record the changes (which pushes them onto the stash stack). Most people use this to save changes before updating the tree as described above. They then use `git stash apply` to re-apply them to the tree. The stash is a stack of changes that can be examined with `git stash list`. The git-stash man page (https://git-scm.com/docs/git-stash) has all the details. This method is suitable when you have tiny tweaks to the tree. When you have anything non trivial, you'll likely be better off keeping a local branch and rebasing. Stashing is also integrated with the `git pull` command: just add `--autostash` to the command line. ===== Keeping a local branch [[keeping_a_local_branch]] It is much easier to keep a local branch with Git than Subversion. In Subversion you need to merge the commit, and resolve the conflicts. This is manageable, but can lead to a convoluted history that's hard to upstream should that ever be necessary, or hard to replicate if you need to do so. Git also allows one to merge, along with the same problems. That's one way to manage the branch, but it's the least flexible. In addition to merging, Git supports the concept of 'rebasing' which avoids these issues. The `git rebase` command replays all the commits of a branch at a newer location on the parent branch. We will cover the most common scenarios that arise using it. ====== Create a branch Let's say you want to make a change to FreeBSD's ls command to never, ever do color. There are many reasons to do this, but this example will use that as a baseline. The FreeBSD ls command changes from time to time, and you'll need to cope with those changes. Fortunately, with Git rebase it usually is automatic. [source,shell] .... % cd src % git checkout main % git checkout -b no-color-ls % cd bin/ls % vi ls.c # hack the changes in % git diff # check the changes diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 7378268867ef..cfc3f4342531 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#undef COLORLS #ifdef COLORLS #include #include % # these look good, make the commit... % git commit ls.c .... The commit will pop you into an editor to describe what you've done. Once you enter that, you have your own **local** branch in the Git repo. Build and install it like you normally would, following the directions in the handbook. Git differs from other version control systems in that you have to tell it explicitly which files to commit. I have opted to do it on the commit command line, but you can also do it with `git add` which many of the more in depth tutorials cover. ====== Time to update When it is time to bring in a new version, it is almost the same as w/o the branches. You would update like you would above, but there is one extra command before you update, and one after. The following assumes you are starting with an unmodified tree. It is important to start rebasing operations with a clean tree (Git requires this). [source,shell] .... % git checkout main % git pull --ff-only % git rebase -i main no-color-ls .... This will bring up an editor that lists all the commits in it. For this example, do not change it at all. This is typically what you are doing while updating the baseline (though you also use the Git rebase command to curate the commits you have in the branch). Once you are done with the above, you have to move the commits to ls.c forward from the old version of FreeBSD to the newer one. Sometimes there are merge conflicts. That is OK. Do not panic. Instead, handle them the same as any other merge conflicts. To keep it simple, I will just describe a common issue that may arise. A pointer to a complete treatment can be found at the end of this section. Let's say the includes changes upstream in a radical shift to terminfo as well as a name change for the option. When you updated, you might see something like this: [source,shell] .... Auto-merging bin/ls/ls.c CONFLICT (content): Merge conflict in bin/ls/ls.c error: could not apply 646e0f9cda11... no color ls Resolve all conflicts manually, mark them as resolved with "git add/rm ", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 646e0f9cda11... no color ls .... which looks scary. If you bring up an editor, you will see it is a typical 3-way merge conflict resolution that you may be familiar with from other source code systems (the rest of ls.c has been omitted): [source,shell] .... <<<<<<< HEAD #ifdef COLORLS_NEW #include ======= #undef COLORLS #ifdef COLORLS #include >>>>>>> 646e0f9cda11... no color ls .... The new code is first, and your code is second. The right fix here is to just add a #undef COLORLS_NEW before #ifdef and then delete the old changes: [source,shell] .... #undef COLORLS_NEW #ifdef COLORLS_NEW #include .... save the file. The rebase was interrupted, so you have to complete it: [source,shell] .... % git add ls.c % git rebase --continue .... which tells Git that ls.c has been fixed and to continue the rebase operation. Since there was a conflict, you will get kicked into the editor to update the commit message if necessary. If the commit message is still accurate, just exit the editor. If you get stuck during the rebase, do not panic. git rebase --abort will take you back to a clean slate. It is important, though, to start with an unmodified tree. An aside: The above mentioned `git reflog` comes in handy here, as it will have a list of all the (intermediate) commits that you can view or inspect or cherry-pick. For more on this topic, https://www.freecodecamp.org/news/the-ultimate-guide-to-git-merge-and-git-rebase/ provides a rather extensive treatment. It is a good resource for issues that arise occasionally but are too obscure for this guide. ===== Switching to a Different FreeBSD Branch If you wish to shift from stable/{rel-latest-major} to the current branch. If you have a deep clone, the following will suffice: [source,shell] .... % git checkout main % # build and install here... .... If you have a local branch, though, there are one or two caveats. First, rebase will rewrite history, so you will likely want to do something to save it. Second, jumping branches tends to cause more conflicts. If we pretend the example above was relative to stable/{rel-latest-major}, then to move to `main`, I'd suggest the following: [source,shell,subs=attributes] .... % git checkout no-color-ls % git checkout -b no-color-ls-stable-{rel-latest-major} # create another name for this branch % git rebase -i stable/{rel-latest-major} no-color-ls --onto main .... What the above does is checkout no-color-ls. Then create a new name for it (`no-color-ls-stable-{rel-latest-major}`) in case you need to get back to it. Then you rebase onto the `main` branch. This will find all the commits to the current no-color-ls branch (back to where it meets up with the stable/{rel-latest-major} branch) and then it will replay them onto the `main` branch creating a new no-color-ls branch there (which is why I had you create a place holder name). [[mfc-with-git]] === MFC (Merge From Current) Procedures ==== Summary MFC workflow can be summarized as `git cherry-pick -x` plus `git commit --amend` to adjust the commit message. For multiple commits, use `git rebase -i` to squash them together and edit the commit message. ==== Single commit MFC [source,shell,subs=attributes] .... % git checkout stable/{rel-latest-major} % git cherry-pick -x $HASH --edit .... For MFC commits, for example a vendor import, you would need to specify one parent for cherry-pick purposes. Normally, that would be the "first parent" of the branch you are cherry-picking from, so: [source,shell,subs=attributes] .... % git checkout stable/{rel-latest-major} % git cherry-pick -x $HASH -m 1 --edit .... If things go wrong, you'll either need to abort the cherry-pick with `git cherry-pick --abort` or fix it up and do a `git cherry-pick --continue`. Once the cherry-pick is finished, push with `git push`. If you get an error due to losing the commit race, use `git pull --rebase` and try to push again. ==== MFC to RELENG branch MFCs to branches that require approval require a bit more care. The process is the same for either a typical merge or an exceptional direct commit. * Merge or direct commit to the appropriate `stable/X` branch first before merging to the `releng/X.Y` branch. * Use the hash that's in the `stable/X` branch for the MFC to `releng/X.Y` branch. * Leave both "cherry picked from" lines in the commit message. * Be sure to add the `Approved by:` line when you are in the editor. [source,shell,subs=attributes] .... % git checkout releng/{rel-latest-next} % git cherry-pick -x $HASH --edit .... If you forget to add the `Approved by:` line, you can do a `git commit --amend` to edit the commit message before you push the change. ==== Multiple commit MFC [source,shell] .... % git checkout -b tmp-branch stable/X % for h in $HASH_LIST; do git cherry-pick -x $h; done % git rebase -i stable/X # mark each of the commits after the first as 'squash' # Update the commit message to reflect all elements of commit, if necessary. # Be sure to retain the "cherry picked from" lines. % git push freebsd HEAD:stable/X .... If the push fails due to losing the commit race, rebase and try again: [source,shell] .... % git checkout stable/X % git pull % git checkout tmp-branch % git rebase stable/X % git push freebsd HEAD:stable/X .... Once the MFC is complete, you can delete the temporary branch: [source,shell] .... % git checkout stable/X % git branch -d tmp-branch .... ==== MFC a vendor import Vendor imports are the only thing in the tree that creates a merge commit in the `main` branch. Cherry picking merge commits into stable/XX presents an additional difficulty because there are two parents for a merge commit. Generally, you'll want the first parent's diff since that's the diff to `main` (though there may be some exceptions). [source,shell] .... % git cherry-pick -x -m 1 $HASH .... is typically what you want. This will tell cherry-pick to apply the correct diff. There are some, hopefully, rare cases where it's possible that the `main` branch was merged backwards by the conversion script. Should that be the case (and we've not found any yet), you'd change the above to `-m 2` to pickup the proper parent. Just do: [source,shell] .... % git cherry-pick --abort % git cherry-pick -x -m 2 $HASH .... to do that. The `--abort` will cleanup the failed first attempt. ==== Redoing a MFC If you do a MFC, and it goes horribly wrong and you want to start over, then the easiest way is to use `git reset --hard` like so: [source,shell,subs=attributes] .... % git reset --hard freebsd/stable/{rel-latest-major} .... though if you have some revs you want to keep, and others you don't, using `git rebase -i` is better. ==== Considerations when MFCing When committing source commits to stable and releng branches, we have the following goals: * Clearly mark direct commits distinct from commits that land a change from another branch. * Avoid introducing known breakage into stable and releng branches. * Allow developers to determine which changes have or have not been landed from one branch to another. With Subversion, we used the following practices to achieve these goals: * Using `MFC` and `MFS` tags to mark commits that merged changes from another branch. * Squashing fixup commits into the main commit when merging a change. * Recording mergeinfo so that `svn mergeinfo --show-revs` worked. With Git, we will need to use different strategies to achieve the same goals. This document aims to define best practices when merging source commits using Git that achieve these goals. In general, we aim to use Git's native support to achieve these goals rather than enforcing practices built on Subversion's model. One general note: due to technical differences with Git, we will not be using Git "merge commits" (created via `git merge`) in stable or releng branches. Instead, when this document refers to "merge commits", it means a commit originally made to `main` that is replicated or "landed" to a stable branch, or a commit from a stable branch that is replicated to a releng branch with some variation of `git cherry-pick`. ==== Finding Eligible Hashes to MFC Git provides some built-in support for this via the `git cherry` and `git log --cherry` commands. These commands compare the raw diffs of commits (but not other metadata such as log messages) to determine if two commits are identical. This works well when each commit from `main` is landed as a single commit to a stable branch, but it falls over if multiple commits from `main` are squashed together as a single commit to a stable branch. The project makes extensive use of `git cherry-pick -x` with all lines preserved to work around these difficulties and is working on automated tooling to take advantage of this. ==== Commit message standards ===== Marking MFCs The project has adopted the following practice for marking MFCs: * Use the `-x` flag with `git cherry-pick`. This adds a line to the commit message that includes the hash of the original commit when merging. Since it is added by Git directly, committers do not have to manually edit the commit log when merging. When merging multiple commits, keep all the "cherry picked from" lines. ===== Trim Metadata? One area that was not clearly documented with Subversion (or even CVS) is how to format metadata in log messages for MFC commits. Should it include the metadata from the original commit unchanged, or should it be altered to reflect information about the MFC commit itself? Historical practice has varied, though some of the variance is by field. For example, MFCs that are relevant to a PR generally include the PR field in the MFC so that MFC commits are included in the bug tracker's audit trail. Other fields are less clear. For example, Phabricator shows the diff of the last commit tagged to a review, so including Phabricator URLs replaces the main commit with the landed commits. The list of reviewers is also not clear. If a reviewer has approved a change to `main`, does that mean they have approved the MFC commit? Is that true if it's identical code only, or with merely trivial rework? It's clearly not true for more extensive reworks. Even for identical code what if the commit doesn't conflict but introduces an ABI change? A reviewer may have ok'd a commit for `main` due to the ABI breakage but may not approve of merging the same commit as-is. One will have to use one's best judgment until clear guidelines can be agreed upon. For MFCs regulated by re@, new metadata fields are added, such as the Approved by tag for approved commits. This new metadata will have to be added via `git commit --amend` or similar after the original commit has been reviewed and approved. We may also want to reserve some metadata fields in MFC commits such as Phabricator URLs for use by re@ in the future. Preserving existing metadata provides a very simple workflow. Developers use `git cherry-pick -x` without having to edit the log message. If instead we choose to adjust metadata in MFCs, developers will have to edit log messages explicitly via the use of `git cherry-pick --edit` or `git commit --amend`. However, as compared to svn, at least the existing commit message can be pre-populated and metadata fields can be added or removed without having to re-enter the entire commit message. The bottom line is that developers will likely need to curate their commit message for MFCs that are non-trivial. [[vendor-import-git]] === Vendor Imports with Git This section describes the vendor import procedure with Git in detail. ==== Branch naming convention All vendor branches and tags start with `vendor/`. These branches and tags are visible by default. [NOTE] ==== This chapter follows the convention that the `freebsd` origin is the origin name for the official FreeBSD Git repository. If you use a different convention, replace `freebsd` with the name you use instead in the examples below. ==== We will explore an example for updating NetBSD's mtree that is in our tree. The vendor branch for this is `vendor/NetBSD/mtree`. ==== Updating an old vendor import The vendor trees usually have only the subset of the third-party software that is appropriate to FreeBSD. These trees are usually tiny in comparison to the FreeBSD tree. Git worktrees are thus quite small and fast and the preferred method to use. Make sure that whatever directory you choose below (the `../mtree`) does not currently exist. [source,shell] .... % git worktree add ../mtree vendor/NetBSD/mtree .... ==== Update the Sources in the Vendor Branch Prepare a full, clean tree of the vendor sources. Import everything but merge only what is needed. This example assumes the NetBSD source is checked out from their GitHub mirror in `~/git/NetBSD`. Note that "upstream" might have added or removed files, so we want to make sure deletions are propagated as well. package:net/rsync[] is commonly installed, so I'll use that. [source,shell] .... % cd ../mtree % rsync -va --del --exclude=".git" ~/git/NetBSD/usr.sbin/mtree/ . % git add -A % git status ... % git diff --staged ... % git commit -m "Vendor import of NetBSD's mtree at 2020-12-11" [vendor/NetBSD/mtree 8e7aa25fcf1] Vendor import of NetBSD's mtree at 2020-12-11 7 files changed, 114 insertions(+), 82 deletions(-) % git tag -a vendor/NetBSD/mtree/20201211 .... It is critical to verify that the source code you are importing comes from a trustworthy source. Many open-source projects use cryptographic signatures to sign code changes, git tags, and/or source code tarballs. Always verify these signatures, and use isolation mechanisms like jails, chroot, in combination with a dedicated, non-privileged user account that is different from the one you regularly use (see the Updating the FreeBSD source tree section below for more details), until you are confident that the source code you are importing looks safe. Following the upstream development and occasionally reviewing the upstream code changes can greatly help in improving code quality and benefit everyone involved. It is also a good idea to examine the git diff results before importing them into the vendor area. Always run the `git diff` and `git status` commands and examine the results carefully. When in doubt, it is useful to do a `git annotate` on the vendor branch or the upstream git repository to see who and why a change was made. In the example above we used `-m` to illustrate, but you should compose a proper message in an editor (using a commit message template). It is also important to create an annotated tag using `git tag -a`, otherwise the push will be rejected. Only annotated tags are allowed to be pushed. The annotated tag gives you a chance to enter a commit message. Enter the version you are importing, along with any salient new features or fixes in that version. ==== Updating the FreeBSD Copy At this point you can push the import to `vendor` into our repo. [source,shell] .... % git push --follow-tags freebsd vendor/NetBSD/mtree .... `--follow-tags` tells `git push` to also push tags associated with the locally committed revision. ==== Updating the FreeBSD source tree Now you need to update the mtree in FreeBSD. The sources live in `contrib/mtree` since it is upstream software. From time to time, we may have to make changes to the contributed code to better satisfy FreeBSD's needs. Whenever possible, please try to contribute the local changes back to the upstream projects, this helps them to better support FreeBSD, and also saves your time for future conflict resolutions when importing updates. [source,shell] .... % cd ../src % git subtree merge -P contrib/mtree vendor/NetBSD/mtree .... This would generate a subtree merge commit of `contrib/mtree` against the local `vendor/NetBSD/mtree` branch. Examine the diff from the merge result and the contents of the upstream branch. If the merge reduced our local changes to more trivial difference like blank line or indenting changes, try amending the local changes to reduce diff against upstream, or try to contribute the remaining changes back to the upstream project. If there were conflicts, you would need to fix them before committing. Include details about the changes being merged in the merge commit message. Some open-source software includes a `configure` script that generates files used to define how the code is built; usually, these generated files like `config.h` should be updated as part of the import process. When doing this, always keep in mind that these scripts are executable code running under the current user's credentials. This process should always be run in an isolated environment, ideally inside a jail that does not have network access, and with an unprivileged account; or, at minimum, a dedicated account that is different from the user account you normally use for everyday purposes or for pushing to the FreeBSD source code repository. This minimizes the risk of encountering bugs that can cause data loss or, in worse cases, maliciously planted code. Using an isolated jail also prevents the configure scripts from detecting locally installed software packages, which may lead to unexpected results. When testing your changes, run them in a chroot or jailed environment, or even within a virtual machine first, especially for kernel or library modifications. This approach helps prevent adverse interactions with your working environment. It can be particularly beneficial for changes to libraries that many base system components use, among others. ==== Rebasing your change against latest FreeBSD source tree Because the current policy recommends against using merges, if the upstream FreeBSD `main` moved forward before you get a chance to push, you would have to redo the merge. Regular `git rebase` or `git pull --rebase` doesn't know how to rebase a merge commit **as a merge commit**, so instead of that you would have to recreate the commit. The following steps should be taken to easily recreate the merge commit as if `git rebase --merge-commits` worked properly: * cd to the top of the repo * Create a side branch `XXX` with the **contents** of the merged tree. * Update this side branch `XXX` to be merged and up-to-date with FreeBSD's `main` branch. ** In the worst case scenario, you would still have to resolve merge conflicts, if there was any, but this should be really rare. ** Resolve conflicts, and collapse multiple commits down to 1 if need be (without conflicts, there's no collapse needed) * checkout `main` * create a branch `YYY` (allows for easier unwinding if things go wrong) * Re-do the subtree merge * Instead of resolving any conflicts from the subtree merge, checkout the contents of XXX on top of it. ** The trailing `.` is important, as is being at the top level of the repo. ** Rather than switching branches to XXX, it splats the contents of XXX on top of the repo * Commit the results with the prior commit message (the example assumes there's only one merge on the XXX branch). * Make sure the branches are the same. * Do whatever review you need, including having others check it out if you think that's needed. * Push the commit, if you 'lost the race' again, just redo these steps again (see below for a recipe) * Delete the branches once the commit is upstream. They are throw-a-way. The commands one would use, following the above example of mtree, would be like so (the `#` starts a comment to help link commands to descriptions above): [source,shell] .... % cd ../src # CD to top of tree % git checkout -b XXX # create new throw-away XXX branch for merge % git fetch freebsd # Get changes from upstream from upstream % git merge freebsd/main # Merge the changes and resolve conflicts % git checkout -b YYY freebsd/main # Create new throw-away YYY branch for redo % git subtree merge -P contrib/mtree vendor/NetBSD/mtree # Redo subtree merge % git checkout XXX . # XXX branch has the conflict resolution % git commit -c XXX~1 # -c reuses the commit message from commit before rebase % git diff XXX YYY # Should be empty % git show YYY # Should only have changes you want, and be a merge commit from vendor branch .... Note: if things go wrong with the commit, you can reset the `YYY` branch by reissuing the checkout command that created it with -B to start over: [source,shell] .... % git checkout -B YYY freebsd/main # Create new throw-away YYY branch if starting over is just going to be easier .... ==== Pushing the changes Once you think you have a set of changes that are good, you can push it to a fork off GitHub or GitLab for others to review. One nice thing about Git is that it allows you to publish rough drafts of your work for others to review. While Phabricator is good for content review, publishing the updated vendor branch and merge commits lets others check the details as they will eventually appear in the repository. After review, when you are sure it is a good change, you can push it to the FreeBSD repo: [source,shell] .... % git push freebsd YYY:main # put the commit on upstream's 'main' branch % git branch -D XXX # Throw away the throw-a-way branches. % git branch -D YYY .... Note: I used `XXX` and `YYY` to make it obvious they are terrible names and should not leave your machine. If you use such names for other work, then you'll need to pick different names, or risk losing the other work. There is nothing magic about these names. Upstream will not allow you to push them, but never the less, please pay attention to the exact commands above. Some commands use syntax that differs only slightly from typical uses and that different behavior is critical to this recipe working. ==== How to redo things if need be If you've tried to do the push in the previous section and it fails, then you should do the following to 'redo' things. This sequence keeps the commit with the commit message always at XXX~1 to make committing easier. [source,shell] .... % git checkout -B XXX YYY # recreate that throw-away-branch XXX and switch to it % git merge freebsd/main # Merge the changes and resolve conflicts % git checkout -B YYY freebsd/main # Recreate new throw-away YYY branch for redo % git subtree merge -P contrib/mtree vendor/NetBSD/mtree # Redo subtree merge % git checkout XXX . # XXX branch has the conflict resolution % git commit -c XXX~1 # -c reuses the commit message from commit before rebase .... Then go check it out as above and push as above when ready. === Creating a new vendor branch There are a number of ways to create a new vendor branch. The recommended way is to create a new repository and then merge that with FreeBSD. If one is importing `glorbnitz` into the FreeBSD tree, release 3.1415. For the sake of simplicity, we will not trim this release. It is a simple user command that puts the nitz device into different magical glorb states and is small enough trimming will not save much. ==== Create the repo [source,shell] .... % cd /some/where % mkdir glorbnitz % cd glorbnitz % git init % git checkout -b vendor/glorbnitz .... At this point, you have a new repo, where all new commits will go on the `vendor/glorbnitz` branch. Git experts can also do this right in their FreeBSD clone, using `git checkout --orphan vendor/glorbnitz` if they are more comfortable with that. ==== Copy the sources in Since this is a new import, you can just cp the sources in, or use tar or even rsync as shown above. And we will add everything, assuming no dot files. [source,shell] .... % cp -r ~/glorbnitz/* . % git add * .... At this point, you should have a pristine copy of glorbnitz ready to commit. [source,shell] .... % git commit -m "Import GlorbNitz frobnosticator revision 3.1415" .... As above, I used `-m` for simplicity, but you should likely create a commit message that explains what a Glorb is and why you'd use a Nitz to get it. Not everybody will know so, for your actual commit, you should follow the crossref:committers-guide[commit-log-message,commit log message] section instead of emulating the brief style used here. ==== Now import it into our repository Now you need to import the branch into our repository. [source,shell] .... % cd /path/to/freebsd/repo/src % git remote add glorbnitz /some/where/glorbnitz % git fetch glorbnitz vendor/glorbnitz .... Note the vendor/glorbnitz branch is in the repo. At this point the `/some/where/glorbnitz` can be deleted, if you like. It was only a means to an end. // perhaps the real treasure was the friends it made along the way... ==== Tag and push Steps from here on out are much the same as they are in the case of updating a vendor branch, though without the updating the vendor branch step. [source,shell] .... % git worktree add ../glorbnitz vendor/glorbnitz % cd ../glorbnitz % git tag --annotate vendor/glorbnitz/3.1415 # Make sure the commit is good with "git show" % git push --follow-tags freebsd vendor/glorbnitz .... By 'good' we mean: . All the right files are present . None of the wrong files are present . The vendor branch points at something sensible . The tag looks good, and is annotated . The commit message for the tag has a quick summary of what's new since the last tag ==== Time to finally merge it into the base tree [source,shell] .... % cd ../src % git subtree add -P contrib/glorbnitz vendor/glorbnitz # Make sure the commit is good with "git show" % git commit --amend # one last sanity check on commit message % git push freebsd .... Here 'good' means: . All the right files, and none of the wrong ones, were merged into contrib/glorbnitz. . No other changes are in the tree. . The commit messages look crossref:committers-guide[commit-log-message,good]. It should contain a summary of what's changed since the last merge to the FreeBSD `main` branch and any caveats. . `RELNOTES` and `UPDATING` should be updated if there is anything of note, such as user visible changes, important upgrade concerns, etc. [NOTE] ==== This hasn't connected `glorbnitz` to the build yet. How so do that is specific to the software being imported and is beyond the scope of this tutorial. ==== ===== Keeping current So, time passes. It's time now to update the tree for the latest changes upstream. When you checkout `main` make sure that you have no diffs. It's a lot easier to commit those to a branch (or use `git stash`) before doing the following. If you are used to `git pull`, we strongly recommend using the `--ff-only` option, and further setting it as the default option. Alternatively, `git pull --rebase` is useful if you have changes staged in the `main` branch. [source,shell] .... % git config --global pull.ff only .... You may need to omit the --global if you want this setting to apply to only this repository. [source,shell] .... % cd freebsd-src % git checkout main % git pull (--ff-only|--rebase) .... There is a common trap, that the combination command `git pull` will try to perform a merge, which would sometimes creates a merge commit that didn't exist before. This can be harder to recover from. The longer form is also recommended. [source,shell] .... % cd freebsd-src % git checkout main % git fetch freebsd % git merge --ff-only freebsd/main .... These commands reset your tree to the `main` branch, and then update it from where you pulled the tree from originally. It's important to switch to `main` before doing this so it moves forward. Now, it's time to move the changes forward: [source,shell] .... % git rebase -i main working .... This will bring up an interactive screen to change the defaults. For now, just exit the editor. Everything should just apply. If not, then you'll need to resolve the diffs. https://docs.github.com/en/free-pro-team@latest/github/using-git/resolving-merge-conflicts-after-a-git-rebase[This github document] can help you navigate this process. [[git-push-upstream]] ===== Time to push changes upstream First, ensure that the push URL is properly configured for the upstream repository. [source,shell] .... % git remote set-url --push freebsd ssh://git@gitrepo.freebsd.org/src.git .... Then, verify that user name and email are configured right. We require that they exactly match the passwd entry in FreeBSD cluster. Use [source,shell] .... freefall% gen-gitconfig.sh .... on freefall.freebsd.org to get a recipe that you can use directly, assuming /usr/local/bin is in the PATH. The below command merges the `working` branch into the upstream `main` branch. It's important that you curate your changes to be just like you want them in the FreeBSD source repo before doing this. This syntax pushes the `working` branch to `main`, moving the `main` branch forward. You will only be able to do this if this results in a linear change to `main` (e.g. no merges). [source,shell] .... % git push freebsd working:main .... If your push is rejected due to losing a commit race, rebase your branch before trying again: [source,shell] .... % git checkout working % git fetch freebsd % git rebase freebsd/main % git push freebsd working:main .... [[git-push-upstream-alt]] ===== Time to push changes upstream (alternative) Some people find it easier to merge their changes to their local `main` before pushing to the remote repository. Also, `git arc stage` moves changes from a branch to the local `main` when you need to do a subset of a branch. The instructions are similar to the prior section: [source,shell] .... % git checkout main % git merge --ff-only `working` % git push freebsd .... If you lose the race, then try again with [source,shell] .... % git pull --rebase % git push freebsd .... These commands will fetch the most recent `freebsd/main` and then rebase the local `main` changes on top of that, which is what you want when you lose the commit race. Note: merging vendor branch commits will not work with this technique. ===== Finding the Subversion Revision You'll need to make sure that you've fetched the notes (see the crossref:committers-guide[git-mini-daily-use, Daily use]for details). Once you have these, notes will show up in the git log command like so: [source,shell] .... % git log .... If you have a specific version in mind, you can use this construct: [source,shell] .... % git log --grep revision=XXXX .... to find the specific revision. The hex number after 'commit' is the hash you can use to refer to this commit. [[git-faq]] === Git FAQ This section provides a number of targeted answers to questions that are likely to come up often for users and developers. [NOTE] ==== We use the common convention of having the origin for the FreeBSD repository being 'freebsd' rather than the default 'origin' to allow people to use that for their own development and to minimize "whoops" pushes to the wrong repository. ==== ==== Users ===== How do I track -current and -stable with only one copy of the repository? **Q:** Although disk space is not a huge issue, it's more efficient to use only one copy of the repository. With SVN mirroring, I could checkout multiple trees from the same repository. How do I do this with Git? **A:** You can use Git worktrees. There's a number of ways to do this, but the simplest way is to use a clone to track -current, and a worktree to track stable releases. While using a 'bare repository' has been put forward as a way to cope, it's more complicated and will not be documented here. First, you need to clone the FreeBSD repository, shown here cloning into `freebsd-current` to reduce confusion. $URL is whatever mirror works best for you: [source,shell] .... % git clone -o freebsd --config remote.freebsd.fetch='+refs/notes/*:refs/notes/*' $URL freebsd-current .... then once that's cloned, you can simply create a worktree from it: [source,shell] .... % cd freebsd-current % git worktree add ../freebsd-stable-12 stable/12 .... this will checkout `stable/12` into a directory named `freebsd-stable-12` that's a peer to the `freebsd-current` directory. Once created, it's updated very similarly to how you might expect: [source,shell] .... % cd freebsd-current % git checkout main % git pull --ff-only # changes from upstream now local and current tree updated % cd ../freebsd-stable-12 % git merge --ff-only freebsd/stable/12 # now your stable/12 is up to date too .... I recommend using `--ff-only` because it's safer and you avoid accidentally getting into a 'merge nightmare' where you have an extra change in your tree, forcing a complicated merge rather than a simple one. Here's https://adventurist.me/posts/00296[a good writeup] that goes into more detail. ==== Developers ===== Ooops! I committed to `main`, instead of another branch. **Q:** From time to time, I goof up and mistakenly commit to the `main` branch. What do I do? **A:** First, don't panic. Second, don't push. In fact, you can fix almost anything if you haven't pushed. All the answers in this section assume no push has happened. The following answer assumes you committed to `main` and want to create a branch called `issue`: [source,shell] .... % git checkout -b issue # Create the 'issue' branch % git checkout -B main freebsd/main # Reset main to upstream % git checkout issue # Back to where you were .... ===== Ooops! I committed something to the wrong branch! **Q:** I was working on feature on the `wilma` branch, but accidentally committed a change relevant to the `fred` branch in 'wilma'. What do I do? **A:** The answer is similar to the previous one, but with cherry picking. This assumes there's only one commit on wilma, but will generalize to more complicated situations. It also assumes that it's the last commit on wilma (hence using wilma in the `git cherry-pick` command), but that too can be generalized. [source,shell] .... # We're on branch wilma % git checkout fred # move to fred branch % git cherry-pick wilma # copy the misplaced commit % git checkout wilma # go back to wilma branch % git reset --hard HEAD^ # move what wilma refers to back 1 commit .... If it is not the last commit, you can cherry-pick that one change from wilma onto fred, then use `git rebase -i` to remove the change from wilma. [source,shell] .... # We're on branch wilma % git checkout fred # move to fred branch % git cherry-pick HASH_OF_CHANGE # copy the misplaced commit % git rebase -i main wilma # drop the cherry-picked change .... **Q:** But what if I want to commit a few changes to `main`, but keep the rest in `wilma` for some reason? **A:** The same technique above also works if you are wanting to 'land' parts of the branch you are working on into `main` before the rest of the branch is ready (say you noticed an unrelated typo, or fixed an incidental bug). You can cherry pick those changes into `main`, then push to the parent repository. Once you've done that, cleanup couldn't be simpler: just `git rebase -i`. Git will notice you've done this and skip the common changes automatically (even if you had to change the commit message or tweak the commit slightly). There's no need to switch back to wilma to adjust it: just rebase! **Q:** I want to split off some changes from branch `wilma` into branch `fred` **A:** The more general answer would be the same as the previous. You'd checkout/create the `fred` branch, cherry pick the changes you want from `wilma` one at a time, then rebase `wilma` to remove those changes you cherry picked. `git rebase -i main wilma` will toss you into an editor, and remove the `pick` lines that correspond to the commits you copied to `fred`. If all goes well, and there are no conflicts, you're done. If not, you'll need to resolve the conflicts as you go. The other way to do this would be to checkout `wilma` and then create the branch `fred` to point to the same point in the tree. You can then `git rebase -i` both these branches, selecting the changes you want in `fred` or `wilma` by retaining the pick likes, and deleting the rest from the editor. Some people would create a tag/branch called `pre-split` before starting in case something goes wrong in the split. You can undo it with the following sequence: [source,shell] .... % git checkout pre-split # Go back % git branch -D fred # delete the fred branch % git checkout -B wilma # reset the wilma branch % git branch -d pre-split # Pretend it didn't happen .... The last step is optional. If you are going to try again to split, you'd omit it. **Q:** But I did things as I read along and didn't see your advice at the end to create a branch, and now `fred` and `wilma` are all screwed up. How do I find what `wilma` was before I started. I don't know how many times I moved things around. **A:** All is not lost. You can figure out it, so long as it hasn't been too long, or too many commits (hundreds). So I created a wilma branch and committed a couple of things to it, then decided I wanted to split it into fred and wilma. Nothing weird happened when I did that, but let's say it did. The way to look at what you've done is with the `git reflog`: [source,shell] .... % git reflog 6ff9c25 (HEAD -> wilma) HEAD@{0}: rebase -i (finish): returning to refs/heads/wilma 6ff9c25 (HEAD -> wilma) HEAD@{1}: rebase -i (start): checkout main 869cbd3 HEAD@{2}: rebase -i (start): checkout wilma a6a5094 (fred) HEAD@{3}: rebase -i (finish): returning to refs/heads/fred a6a5094 (fred) HEAD@{4}: rebase -i (pick): Encourage contributions 1ccd109 (freebsd/main, main) HEAD@{5}: rebase -i (start): checkout main 869cbd3 HEAD@{6}: rebase -i (start): checkout fred 869cbd3 HEAD@{7}: checkout: moving from wilma to fred 869cbd3 HEAD@{8}: commit: Encourage contributions ... % .... Here we see the changes I've made. You can use it to figure out where things went wrong. I'll just point out a few things here. The first one is that HEAD@{X} is a 'commitish' thing, so you can use that as an argument to a command. Although if that command commits anything to the repository, the X numbers change. You can also use the hash (first column). Next, 'Encourage contributions' was the last commit I made to `wilma` before I decided to split things up. You can also see the same hash is there when I created the `fred` branch to do that. I started by rebasing `fred` and you see the 'start', each step, and the 'finish' for that process. While we don't need it here, you can figure out exactly what happened. Fortunately, to fix this, you can follow the prior answer's steps, but with the hash `869cbd3` instead of `pre-split`. While that seems a bit verbose, it's easy to remember since you're doing one thing at a time. You can also stack: [source,shell] .... % git checkout -B wilma 869cbd3 % git branch -D fred .... and you are ready to try again. The `checkout -B` with the hash combines checking out and creating a branch for it. The `-B` instead of `-b` forces the movement of a pre-existing branch. Either way works, which is what's great (and awful) about Git. One reason I tend to use `git checkout -B xxxx hash` instead of checking out the hash, and then creating / moving the branch is purely to avoid the slightly distressing message about detached heads: [source,shell] .... % git checkout 869cbd3 M faq.md Note: checking out '869cbd3'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b HEAD is now at 869cbd3 Encourage contributions % git checkout -B wilma .... this produces the same effect, but I have to read a lot more and severed heads aren't an image I like to contemplate. ===== Ooops! I did a `git pull` and it created a merge commit, what do I do? **Q:** I was on autopilot and did a `git pull` for my development tree and that created a merge commit on `main`. How do I recover? **A:** This can happen when you invoke the pull with your development branch checked out. Many developers use `git pull --rebase` to avoid this situation. Right after the pull, you will have the new merge commit checked out. Git supports a `HEAD^#` syntax to examine the parents of a merge commit: [source,shell] .... git log --oneline HEAD^1 # Look at the first parent's commits git log --oneline HEAD^2 # Look at the second parent's commits .... From those logs, you can easily identify which commit is your development work. Then you simply reset your branch to the corresponding `HEAD^#`: [source,shell] .... git reset --hard HEAD^1 .... In addition, a `git pull --rebase` at this stage will rebase your changes to 'main' to the latest 'freebsd/main'. **Q:** But I also need to fix my `main` branch. How do I do that? **A:** Git keeps track of the remote repository branches in a `freebsd/` namespace. To fix your `main` branch, just make it point to the remote's `main`: [source,shell] .... git branch -f main freebsd/main .... There's nothing magical about branches in Git: they are just labels on a graph that are automatically moved forward by making commits. So the above works because you're just moving a label. There's no metadata about the branch that needs to be preserved due to this. ===== Mixing and matching branches **Q:** So I have two branches `worker` and `async` that I'd like to combine into one branch called `feature` while maintaining the commits in both. **A:** This is a job for cherry pick. [source,shell] .... % git checkout worker % git checkout -b feature # create a new branch % git cherry-pick main..async # bring in the changes .... You now have a new branch called `feature`. This branch combines commits from both branches. You can further curate it with `git rebase`. **Q:** I have a branch called `driver` and I'd like to break it up into `kernel` and `userland` so I can evolve them separately and commit each branch as it becomes ready. **A:** This takes a little bit of prep work, but `git rebase` will do the heavy lifting here. [source,shell] .... % git checkout driver # Checkout the driver % git checkout -b kernel # Create kernel branch % git checkout -b userland # Create userland branch .... Now you have two identical branches. So, it's time to separate out the commits. We'll assume first that all the commits in `driver` go into either the `kernel` or the `userland` branch, but not both. [source,shell] .... % git rebase -i main kernel .... and just include the changes you want (with a 'p' or 'pick' line) and just delete the commits you don't (this sounds scary, but if worse comes to worse, you can throw this all away and start over with the `driver` branch since you've not yet moved it). [source,shell] .... % git rebase -i main userland .... and do the same thing you did with the `kernel` branch. **Q:** Oh great! I followed the above and forgot a commit in the `kernel` branch. How do I recover? **A:** You can use the `driver` branch to find the hash of the commit is missing and cherry pick it. [source,shell] .... % git checkout kernel % git log driver % git cherry-pick $HASH .... **Q:** OK. I have the same situation as the above, but my commits are all mixed up. I need parts of one commit to go to one branch and the rest to go to the other. In fact, I have several. Your rebase method to select sounds tricky. **A:** In this situation, you'd be better off to curate the original branch to separate out the commits, and then use the above method to split the branch. So let's assume that there's just one commit with a clean tree. You can either use `git rebase` with an `edit` line, or you can use this with the commit on the tip. The steps are the same either way. The first thing we need to do is to back up one commit while leaving the changes uncommitted in the tree: [source,shell] .... % git reset HEAD^ .... Note: Do not, repeat do not, add `--hard` here since that also removes the changes from your tree. Now, if you are lucky, the change needing to be split up falls entirely along file lines. In that case you can just do the usual `git add` for the files in each group than do a `git commit`. Note: when you do this, you'll lose the commit message when you do the reset, so if you need it for some reason, you should save a copy (though `git log $HASH` can recover it). If you are not lucky, you'll need to split apart files. There's another tool to do that which you can apply one file at a time. [source,shell] .... git add -i foo/bar.c .... will step through the diffs, prompting you, one at time, whether to include or exclude the hunk. Once you're done, `git commit` and you'll have the remainder in your tree. You can run it multiple times as well, and even over multiple files (though I find it easier to do one file at a time and use the `git rebase -i` to fold the related commits together). ===== Joining the FreeBSD GitHub organization. **Q:** How do I join the FreeBSD GitHub organization? **A:** Please see https://wiki.freebsd.org/GitHub#Joining_the_Organisation[our GitHub Wiki Info] page for details. Briefly, all FreeBSD committers may join. Those who are not committers who request joining will be considered on a case by case basis. ==== Cloning and Mirroring **Q:** I'd like to mirror the entire Git repository, how do I do that? **A:** If all you want to do is mirror, then [source,shell] .... % git clone --mirror $URL .... will do the trick. However, there are two disadvantages to this if you want to use it for anything other than a mirror you'll reclone. First, this is a 'bare repository' which has the repository database, but no checked out worktree. This is great for mirroring, but terrible for day to day work. There's a number of ways around this with `git worktree`: [source,shell] .... % git clone --mirror https://git.freebsd.org/ports.git ports.git % cd ports.git % git worktree add ../ports main % git worktree add ../quarterly branches/2020Q4 % cd ../ports .... But if you aren't using your mirror for further local clones, then it's a poor match. The second disadvantage is that Git normally rewrites the refs (branch name, tags, etc) from upstream so that your local refs can evolve independently of upstream. This means that you'll lose changes if you are committing to this repository on anything other than private project branches. **Q:** So what can I do instead? **A:** Well, you can stuff all of the upstream repository's refs into a private namespace in your local repository. Git clones everything via a 'refspec' and the default refspec is: [source,shell] .... fetch = +refs/heads/*:refs/remotes/freebsd/* .... which says just fetch the branch refs. However, the FreeBSD repository has a number of other things in it. To see those, you can add explicit refspecs for each ref namespace, or you can fetch everything. To setup your repository to do that: [source,shell] .... git config --add remote.freebsd.fetch '+refs/*:refs/freebsd/*' .... which will put everything in the upstream repository into your local repository's `refs/freebsd/` namespace. Please note, that this also grabs all the unconverted vendor branches and the number of refs associated with them is quite large. You'll need to refer to these 'refs' with their full name because they aren't in and of Git's regular namespaces. [source,shell] .... git log refs/freebsd/vendor/zlib/1.2.10 .... would look at the log for the vendor branch for zlib starting at 1.2.10. === Collaborating with others One of the keys to good software development on a project as large as FreeBSD is the ability to collaborate with others before you push your changes to the tree. The FreeBSD project's Git repositories do not, yet, allow user-created branches to be pushed to the repository, and therefore if you wish to share your changes with others you must use another mechanism, such as a hosted GitLab or GitHub, to share changes in a user-generated branch. The following instructions show how to set up a user-generated branch, based on the FreeBSD `main` branch, and push it to GitHub. Before you begin, make sure that your local Git repo is up to date and has the correct origins set crossref:committers-guide[keeping_current,as shown above]. [source,shell] .... % git remote -v freebsd https://git.freebsd.org/src.git (fetch) freebsd ssh://git@gitrepo.freebsd.org/src.git (push) .... The first step is to create a fork of https://github.com/freebsd/freebsd-src[FreeBSD] on GitHub following these https://docs.github.com/en/github/getting-started-with-github/fork-a-repo[guidelines]. The destination of the fork should be your own, personal, GitHub account (gvnn3 in my case). Now add a remote on your local system that points to your fork: [source,shell] .... % git remote add github git@github.com:gvnn3/freebsd-src.git % git remote -v github git@github.com:gvnn3/freebsd-src.git (fetch) github git@github.com:gvnn3/freebsd-src.git (push) freebsd https://git.freebsd.org/src.git (fetch) freebsd ssh://git@gitrepo.freebsd.org/src.git (push) .... With this in place you can create a branch crossref:committers-guide[keeping_a_local_branch,as shown above]. [source,shell] .... % git checkout -b gnn-pr2001-fix .... Make whatever modifications you wish in your branch. Build, test, and once you're ready to collaborate with others it's time to push your changes into your hosted branch. Before you can push you'll have to set the appropriate upstream, as Git will tell you the first time you try to push to your +github+ remote: [source,shell] .... % git push github fatal: The current branch gnn-pr2001-fix has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream github gnn-pr2001-fix .... Setting the push as +git+ advises allows it to succeed: [source,shell] .... % git push --set-upstream github gnn-feature Enumerating objects: 20486, done. Counting objects: 100% (20486/20486), done. Delta compression using up to 8 threads Compressing objects: 100% (12202/12202), done. Writing objects: 100% (20180/20180), 56.25 MiB | 13.15 MiB/s, done. Total 20180 (delta 11316), reused 12972 (delta 7770), pack-reused 0 remote: Resolving deltas: 100% (11316/11316), completed with 247 local objects. remote: remote: Create a pull request for 'gnn-feature' on GitHub by visiting: remote: https://github.com/gvnn3/freebsd-src/pull/new/gnn-feature remote: To github.com:gvnn3/freebsd-src.git * [new branch] gnn-feature -> gnn-feature Branch 'gnn-feature' set up to track remote branch 'gnn-feature' from 'github'. .... Subsequent changes to the same branch will push correctly by default: [source,shell] .... % git push Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 8 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 314 bytes | 1024 bytes/s, done. Total 3 (delta 1), reused 1 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), completed with 1 local object. To github.com:gvnn3/freebsd-src.git 9e5243d7b659..cf6aeb8d7dda gnn-feature -> gnn-feature .... At this point your work is now in your branch on +GitHub+ and you can share the link with other collaborators. [[github-pull-land]] === Landing a github pull request This section documents how to land a GitHub pull request that's submitted against the FreeBSD Git mirrors at GitHub. While this is not an official way to submit patches at this time, sometimes good fixes come in this way and it is easiest just to bring them into a committer's tree and have them pushed into the FreeBSD's tree from there. Similar steps can be used to pull branches from other repositories and land those. When committing pull requests from others, one should take extra care to examine all the changes to ensure they are exactly as represented. Before beginning, make sure that the local Git repo is up to date and has the correct origins set crossref:committers-guide[keeping_current,as shown above]. In addition, make sure to have the following origins: [source,shell] .... % git remote -v freebsd https://git.freebsd.org/src.git (fetch) freebsd ssh://git@gitrepo.freebsd.org/src.git (push) github https://github.com/freebsd/freebsd-src (fetch) github https://github.com/freebsd/freebsd-src (fetch) .... Often pull requests are simple: requests that contain only a single commit. In this case, a streamlined approach may be used, though the approach in the prior section will also work. Here, a branch is created, the change is cherry picked, the commit message adjusted, and sanity-checked before being pushed. The branch `staging` is used in this example but it can be any name. This technique works for any number of commits in the pull request, especially when the changes apply cleanly to the FreeBSD tree. However, when there's multiple commits, especially when minor adjustments are needed, `git rebase -i` works better than `git cherry-pick`. Briefly, these commands create a branch; cherry-picks the changes from the pull request; tests it; adjusts the commit messages; and fast forward merges it back to `main`. The PR number is `$PR` below. When adjusting the message, add `Pull Request: https://github.com/freebsd-src/pull/$PR`. All pull requests committed to the FreeBSD repository should be reviewed by at least one person. This need not be the person committing it, but in that case the person committing it should trust the other reviewers competence to review the commit. Committers that do a code review of pull requests before pushing them into the repo should add a `Reviewed by:` line to the commit, because in this case it is not implicit. Add anybody that reviews and approves the commit on github to `Reviewed by:` as well. As always, care should be taken to ensure the change does what it is supposed to, and that no malicious code is present. [NOTE] ====== In addition, please check to make sure that the pull request author name is not anonymous. Github's web editing interface generates names like: [source,shell] .... Author: github-user <38923459+github-user@users.noreply.github.com> .... A polite request to the author for a better name and/or email should be made. Extra care should be taken to ensure no style issue or malicious code is introduced. ====== [source,shell] .... % git fetch github pull/$PR/head:staging % git rebase -i main staging # to move the staging branch forward, adjust commit message here % git checkout main % git pull --ff-only # to get the latest if time has passed % git checkout main % git merge --ff-only staging % git push freebsd --push-option=confirm-author .... [.procedure] ==== For complicated pull requests that have multiple commits with conflicts, follow the following outline. . checkout the pull request `git checkout github/pull/XXX` . create a branch to rebase `git checkout -b staging` . rebase the `staging` branch to the latest `main` with `git rebase -i main staging` . resolve conflicts and do whatever testing is needed . fast forward the `staging` branch into `main` as above . final sanity check of changes to make sure all is well . push to FreeBSD's Git repository. This will also work when bringing branches developed elsewhere into the local tree for committing. ==== Once finished with the pull request, close it using GitHub's web interface. It is worth noting that if your `github` origin uses `https://`, the only step you'll need a GitHub account for is closing the pull request. [[vcs-history]] == Version Control History The project has moved to crossref:committers-guide[git-primer,git]. The FreeBSD source repository switched from CVS to Subversion on May 31st, 2008. The first real SVN commit is __r179447__. The source repository switched from Subversion to Git on December 23rd, 2020. The last real svn commit is __r368820__. The first real git commit hash is __5ef5f51d2bef80b0ede9b10ad5b0e9440b60518c__. The FreeBSD `doc/www` repository switched from CVS to Subversion on May 19th, 2012. The first real SVN commit is __r38821__. The documentation repository switched from Subversion to Git on December 8th, 2020. The last SVN commit is __r54737__. The first real git commit hash is __3be01a475855e7511ad755b2defd2e0da5d58bbe__. The FreeBSD `ports` repository switched from CVS to Subversion on July 14th, 2012. The first real SVN commit is __r300894__. The ports repository switched from Subversion to Git on April 6, 2021. The last SVN commit is __r569609__ The first real git commit hash is __ed8d3eda309dd863fb66e04bccaa513eee255cbf__. [[conventions]] == Setup, Conventions, and Traditions There are a number of things to do as a new developer. The first set of steps is specific to committers only. These steps must be done by a mentor for those who are not committers. [[conventions-committers]] === For New Committers Those who have been given commit rights to the FreeBSD repositories must follow these steps. * Get mentor approval before committing each of these changes! * All [.filename]#src# commits go to FreeBSD-CURRENT first before being merged to FreeBSD-STABLE. The FreeBSD-STABLE branch must maintain ABI and API compatibility with earlier versions of that branch. Do not merge changes that break this compatibility. [[commit-steps]] [.procedure] ==== *Steps for New Committers* . Add an Author Entity + [.filename]#doc/shared/authors.adoc# - Add an author entity. Later steps depend on this entity, and missing this step will cause the [.filename]#doc/# build to fail. This is a relatively easy task, but remains a good first test of version control skills. . Update the List of Developers and Contributors + [.filename]#doc/shared/contrib-committers.adoc# - Add an entry, which will then appear in the "Developers" section of the extref:{contributors}[Contributors List, staff-committers]. Entries are sorted by last name. + [.filename]#doc/shared/contrib-additional.adoc# - _Remove_ the entry. Entries are sorted by first name. . Add a News Item + [.filename]#doc/website/data/en/news/news.toml# - Add an entry. Look for the other entries that announce new committers and follow the format. Use the date from the commit bit approval email. . Add a PGP Key + `{des}` has written a shell script ([.filename]#doc/documentation/tools/addkey.sh#) to make this easier. See the https://cgit.freebsd.org/doc/plain/documentation/static/pgpkeys/README[README] file for more information. + Use [.filename]#doc/documentation/tools/checkkey.sh# to verify that keys meet minimal best-practices standards. + After adding and checking a key, add both updated files to source control and then commit them. Entries in this file are sorted by last name. + [NOTE] ====== It is very important to have a current PGP/GnuPG key in the repository. The key may be required for positive identification of a committer. For example, the `{admins}` might need it for account recovery. A complete keyring of `FreeBSD.org` users is available for download from link:https://docs.FreeBSD.org/pgpkeys/pgpkeys.txt[https://docs.FreeBSD.org/pgpkeys/pgpkeys.txt]. ====== . Update Mentor and Mentee Information + [.filename]#src/share/misc/committers-.dot# - Add an entry to the current committers section, where _repository_ is `doc`, `ports`, or `src`, depending on the commit privileges granted. + Add an entry for each additional mentor/mentee relationship in the bottom section. . Update git mailmap file + [.filename]#src/.mailmap#, [.filename]#doc/.mailmap#, and [.filename]#ports/.mailmap# - Add an entry for commits you created prior to becoming a FreeBSD committer. + Mapping to your FreeBSD address allows us to track external committers who may be ready for a commit bit more easily. You can also use this to correct old names, misspelled names, etc in the default `git log` output. . Generate a Kerberos Password + See crossref:committers-guide[kerberos-ldap, Kerberos and LDAP web Password for FreeBSD Cluster] to generate or set a Kerberos account for use with other FreeBSD services like the link:https://bugs.freebsd.org/bugzilla/[bug-tracking database] (you get a bug-tracking account as part of that step). . Optional: Enable Wiki Account + link:https://wiki.freebsd.org[FreeBSD Wiki] Account - A wiki account allows sharing projects and ideas. Those who do not yet have an account can follow instructions on the link:https://wiki.freebsd.org/Wiki/About[Wiki/About page] to obtain one. Contact mailto:wiki-admin@FreeBSD.org[wiki-admin@FreeBSD.org] if you need help with your Wiki account. . Optional: Update Wiki Information + Wiki Information - After gaining access to the wiki, some people add entries to the https://wiki.freebsd.org/HowWeGotHere[How We Got Here], https://wiki.freebsd.org/IRC/Nicknames[IRC Nicks], https://wiki.freebsd.org/Community/Dogs[Dogs of FreeBSD], and or https://wiki.freebsd.org/Community/Cats[Cats of FreeBSD] pages. . Optional: Update Ports with Personal Information + [.filename]#ports/astro/xearth/files/freebsd.committers.markers# and [.filename]#src/usr.bin/calendar/calendars/calendar.freebsd# - Some people add entries for themselves to these files to show where they are located or the date of their birthday. . Optional: Prevent Duplicate Mailings + Subscribers to {dev-commits-doc-all}, {dev-commits-ports-all} or {dev-commits-src-all} might wish to unsubscribe to avoid receiving duplicate copies of commit messages and followups. ==== [[conventions-everyone]] === For Everyone [[conventions-everyone-steps]] [.procedure] ==== . Introduce yourself to the other developers, otherwise no one will have any idea who you are or what you are working on. The introduction need not be a comprehensive biography, just write a paragraph or two about who you are, what you plan to be working on as a developer in FreeBSD, and who will be your mentor. Email this to the {developers-name} and you will be on your way! . Log into `freefall.FreeBSD.org` and create a [.filename]#/var/forward/user# (where _user_ is your username) file containing the e-mail address where you want mail addressed to _yourusername_@FreeBSD.org to be forwarded. This includes all of the commit messages as well as any other mail addressed to the {committers-name} and the {developers-name}. Really large mailboxes which have taken up permanent residence on `freefall` may get truncated without warning if space needs to be freed, so forward it or save it elsewhere. + [NOTE] ====== If your e-mail system uses SPF with strict rules, you should exclude `mx2.FreeBSD.org` from SPF checks. ====== + Due to the severe load dealing with SPAM places on the central mail servers that do the mailing list processing, the front-end server does do some basic checks and will drop some messages based on these checks. At the moment proper DNS information for the connecting host is the only check in place but that may change. Some people blame these checks for bouncing valid email. To have these checks turned off for your email, create a file named [.filename]#~/.spam_lover# on `freefall.FreeBSD.org`. + [NOTE] ====== Those who are developers but not committers will not be subscribed to the committers or developers mailing lists. The subscriptions are derived from the access rights. ====== ==== [[smtp-setup]] ==== SMTP Access Setup For those willing to send e-mail messages through the FreeBSD.org infrastructure, follow the instructions below: [.procedure] ==== . Point your mail client at `smtp.FreeBSD.org:587`. . Enable STARTTLS. . Ensure your `From:` address is set to `_yourusername_@FreeBSD.org`. . For authentication, you can use your FreeBSD Kerberos username and password (see crossref:committers-guide[kerberos-ldap, Kerberos and LDAP web Password for FreeBSD Cluster]). The `_yourusername_/mail` principal is preferred, as it is only valid for authenticating to mail resources. + [NOTE] ====== Do not include `@FreeBSD.org` when entering in your username. ====== + .Additional Notes [NOTE] ====== * Will only accept mail from `_yourusername_@FreeBSD.org`. If you are authenticated as one user, you are not permitted to send mail from another. * A header will be appended with the SASL username: (`Authenticated sender: _username_`). * Host has various rate limits in place to cut down on brute force attempts. ====== ==== [[smtp-setup-local-mta]] ===== Using a Local MTA to Forward Emails to the FreeBSD.org SMTP Service It is also possible to use a local MTA to forward locally sent emails to the FreeBSD.org SMTP servers. [[smtp-setup-local-postfix]] .Using Postfix [example] ==== To tell a local Postfix instance that anything from `_yourusername_@FreeBSD.org` should be forwarded to the FreeBSD.org servers, add this to your [.filename]#main.cf#: [.programlisting] .... sender_dependent_relayhost_maps = hash:/usr/local/etc/postfix/relayhost_maps smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous smtp_sasl_password_maps = hash:/usr/local/etc/postfix/sasl_passwd smtp_use_tls = yes .... Create [.filename]#/usr/local/etc/postfix/relayhost_maps# with the following content: [.programlisting] .... yourusername@FreeBSD.org [smtp.freebsd.org]:587 .... Create [.filename]#/usr/local/etc/postfix/sasl_passwd# with the following content: [.programlisting] .... [smtp.freebsd.org]:587 yourusername:yourpassword .... If the email server is used by other people, you may want to prevent them from sending e-mails from your address. To achieve this, add this to your [.filename]#main.cf#: [.programlisting] .... smtpd_sender_login_maps = hash:/usr/local/etc/postfix/sender_login_maps smtpd_sender_restrictions = reject_known_sender_login_mismatch .... Create [.filename]#/usr/local/etc/postfix/sender_login_maps# with the following content: [.programlisting] .... yourusername@FreeBSD.org yourlocalusername .... Where _yourlocalusername_ is the SASL username used to connect to the local instance of Postfix. ==== [[smtp-setup-local-opensmtpd]] .Using OpenSMTPD [example] ==== To tell a local OpenSMTPD instance that anything from `_yourusername_@FreeBSD.org` should be forwarded to the FreeBSD.org servers, add this to your [.filename]#smtpd.conf#: [.programlisting] .... action "freebsd" relay host smtp+tls://freebsd@smtp.freebsd.org:587 auth match from any auth yourlocalusername mail-from "_yourusername_@freebsd.org" for any action "freebsd" .... Where _yourlocalusername_ is the SASL username used to connect to the local instance of OpenSMTPD. Create [.filename]#/usr/local/etc/mail/secrets# with the following content: [.programlisting] .... freebsd yourusername:yourpassword .... ==== [[smtp-setup-local-exim]] .Using Exim [example] ==== To direct a local Exim instance to forward all mail from `_example_@FreeBSD.org` to FreeBSD.org servers, add this to Exim [.filename]#configuration#: [.programlisting] .... Routers section: (at the top of the list): freebsd_send: driver = manualroute domains = !+local_domains transport = freebsd_smtp route_data = ${lookup {${lc:$sender_address}} lsearch {/usr/local/etc/exim/freebsd_send}} Transport Section: freebsd_smtp: driver = smtp tls_certificate= tls_privatekey= tls_require_ciphers = EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+AESGCM:EECDH:EDH+AESGCM:EDH+aRSA:HIGH:!MEDIUM:!LOW:!aNULL:!eNULL:!LOW:!RC4:!MD5:!EXP:!PSK:!SRP:!DSS dkim_domain = dkim_selector = dkim_private_key= dnssec_request_domains = * hosts_require_auth = smtp.freebsd.org Authenticators: freebsd_plain: driver = plaintext public_name = PLAIN client_send = ^example/mail^examplePassword client_condition = ${if eq{$host}{smtp.freebsd.org}} .... Create [.filename]#/usr/local/etc/exim/freebsd_send# with the following content: [.programlisting] .... example@freebsd.org:smtp.freebsd.org::587 .... ==== [[mentors]] === Mentors All new developers have a mentor assigned to them for the first few months. A mentor is responsible for teaching the mentee the rules and conventions of the project and guiding their first steps in the developer community. The mentor is also personally responsible for the mentee's actions during this initial period. For committers: do not commit anything without first getting mentor approval. Document that approval with an `Approved by:` line in the commit message. When the mentor decides that a mentee has learned the ropes and is ready to commit on their own, the mentor announces it with a commit to [.filename]#mentors#. This file is in the [.filename]#admin# orphan branch of each repository. Detailed information on how to access these branches can be found in crossref:committers-guide[admin-branch, "admin" branch]. [[pre-commit-review]] == Pre-Commit Review Code review is one way to increase the quality of software. The following guidelines apply to commits to the `main` (-CURRENT) branch of the `src` repository. Other branches and the `ports` and `docs` trees have their own review policies, but these guidelines generally apply to commits requiring review: * All non-trivial changes should be reviewed before they are committed to the repository. * Reviews may be conducted by email, in Bugzilla, in Phabricator, or by another mechanism. Where possible, reviews should be public. * The developer responsible for a code change is also responsible for making all necessary review-related changes. * Code review can be an iterative process, which continues until the patch is ready to be committed. Specifically, once a patch is sent out for review, it should receive an explicit "looks good" before it is committed. So long as it is explicit, this can take whatever form makes sense for the review method. * Timeouts are not a substitute for review. Sometimes code reviews will take longer than you would hope for, especially for larger features. Accepted ways to speed up review times for your patches are: * Review other people's patches. If you help out, everybody will be more willing to do the same for you; goodwill is our currency. * Ping the patch. If it is urgent, provide reasons why it is important to you to get this patch landed and ping it every couple of days. If it is not urgent, the common courtesy ping rate is one week. Remember that you are asking for valuable time from other professional developers. * Ask for help on mailing lists, IRC, etc. Others may be able to either help you directly, or suggest a reviewer. * Split your patch into multiple smaller patches that build on each other. The smaller your patch, the higher the probability that somebody will take a quick look at it. + When making large changes, it is helpful to keep this in mind from the beginning of the effort as breaking large changes into smaller ones is often difficult after the fact. Developers should participate in code reviews as both reviewers and reviewees. If someone is kind enough to review your code, you should return the favor for someone else. Note that while anyone is welcome to review and give feedback on a patch, only an appropriate subject-matter expert can approve a change. This will usually be a committer who works with the code in question on a regular basis. In some cases, no subject-matter expert may be available. In those cases, a review by an experienced developer is sufficient when coupled with appropriate testing. [[commit-log-message]] == Commit Log Messages This section contains some suggestions and traditions for how commit logs are formatted. === Why are commit messages important? When you commit a change in Git, Subversion, or another version control system (VCS), you're prompted to write some text describing the commit -- a commit message. How important is this commit message? Should you spend some significant effort writing it? Does it really matter if you write simply `fixed a bug`? Most projects have more than one developer and last for some length of time. Commit messages are a very important method of communicating with other developers, in the present and for the future. FreeBSD has hundreds of active developers and hundreds of thousands of commits spanning decades of history. Over that time the developer community has learned how valuable good commit messages are; sometimes these are hard-learned lessons. Commit messages serve at least three purposes: * Communicating with other developers + FreeBSD commits generate email to various mailing lists. These include the commit message along with a copy of the patch itself. Commit messages are also viewed through commands like git log. These serve to make other developers aware of changes that are ongoing; that other developer may want to test the change, may have an interest in the topic and will want to review in more detail, or may have their own projects underway that would benefit from interaction. * Making Changes Discoverable + In a large project with a long history it may be difficult to find changes of interest when investigating an issue or change in behaviour. Verbose, detailed commit messages allow searches for changes that might be relevant. For example, `git log --since 1year --grep 'USB timeout'`. * Providing historical documentation + Commit messages serve to document changes for future developers, perhaps years or decades later. This future developer may even be you, the original author. A change that seems obvious today may be decidedly not so much later on. The `git blame` command annotates each line of a source file with the change (hash and subject line) that brought it in. Having established the importance, here are elements of a good FreeBSD commit message: === Start with a subject line Commit messages should start with a single-line subject that briefly summarizes the change. The subject should, by itself, allow the reader to quickly determine if the change is of interest or not. === Keep subject lines short The subject line should be as short as possible while still retaining the required information. This is to make browsing Git log more efficient, and so that git log --oneline can display the short hash and subject on a single 80-column line. A good rule of thumb is to stay below 67 characters, and aim for about 50 or fewer if possible. === Prefix the subject line with a component, if applicable If the change relates to a specific component the subject line may be prefixed with that component name and a colon (:). If applicable, try to use the same prefix used in previous commits to the same files. ✓ `foo: Add -k option to keep temporary data` Include the prefix in the 67-character limit suggested above, so that `git log --oneline` avoids wrapping. === Capitalize the first letter of the subject Capitalize the first letter of the subject itself. The prefix, if any, is not capitalized unless necessary (e.g., `USB:` is capitalized). === Do not end the subject line with punctuation Do not end with a period or other punctuation. In this regard the subject line is like a newspaper headline. === Separate the subject and body with a blank line Separate the body from the subject with a blank line. Some trivial commits do not require a body, and will have only a subject. ✓ `ls: Fix typo in usage text` === Limit messages to 72 columns `git log` and `git format-patch` indent the commit message by four spaces. Wrapping at 72 columns provides a matching margin on the right edge. Limiting messages to 72 characters also keeps the commit message in formatted patches below RFC 2822's suggested email line length limit of 78 characters. This limit works well with a variety of tools that may render commit messages; line wrapping might be inconsistent with longer line length. === Use the present tense, imperative mood This facilitates short subject lines and provides consistency, including with automatically generated commit messages (e.g., as generated by git revert). This is important when reading a list of commit subjects. Think of the subject as finishing the sentence "when applied, this change will ...". ✓ `foo: Implement the -k (keep) option` + ✗ `foo: Implemented the -k option` + ✗ `This change implements the -k option in foo` + ✗ `-k option added` === Focus on what and why, not how Explain what the change accomplishes and why it is being done, rather than how. Do not assume that the reader is familiar with the issue. Explain the background and motivation for the change. Include benchmark data if you have it. If there are limitations or incomplete aspects of the change, describe them in the commit message. === Consider whether parts of the commit message could be code comments instead Sometimes while writing a commit message you may find yourself writing a sentence or two explaining some tricky or confusing aspect of the change. When this happens consider whether it would be valuable to have that explanation as a comment in the code itself. === Write commit messages for your future self While writing the commit message for a change you have all of the context in mind - what prompted the change, alternate approaches that were considered and rejected, limitations of the change, and so on. Imagine yourself revisiting the change a year or two in the future, and write the commit message in a way that would provide that necessary context. === Commit messages should stand alone You may include references to mailing list postings, benchmark result web sites, or code review links. However, the commit message should contain all of the relevant information in case these references are no longer available in the future. Similarly, a commit may refer to a previous commit, for example in the case of a bug fix or revert. In addition to the commit identifier (revision or hash), include the subject line from the referenced commit (or another suitable brief reference). With each VCS migration (from CVS to Subversion to Git) revision identifiers from previous systems may become difficult to follow. === Include appropriate metadata in a footer As well as including an informative message with each commit, some additional information may be needed. This information consists of one or more lines containing the key word or phrase, a colon, tabs for formatting, and then the additional information. For key words where multiple values make sense (e.g., `PR:` with a comma-separated list of PRs), it is permitted to use the same keyword multiple times to avoid ambiguity or improve readability. The key words or phrases are: [.informaltable] [cols="20%,80%", frame="none"] |=== |`PR:` |The problem report (if any) which is affected (typically, by being closed) by this commit. Multiple PRs may be specified on one line, separated by commas or spaces. |`Reported by:` |The name and e-mail address of the person that reported the issue; for developers, just the username on the FreeBSD cluster. Typically used when there is no PR, for example if the issue was reported on a mailing list. |`Submitted by:` + (discouraged) |Name of an author who submitted a change without providing a full valid patch, especially without a valid email. Submitted patches should have the author set by using `git commit --author` with a full name and valid email. Before the migration to git allowed separate author and committer fields, this was used for contributed patches. |`Reviewed by:` | The name and e-mail address of the person or people that reviewed the change; for developers, just the username on the FreeBSD cluster. If a patch was submitted to a mailing list for review, and the review was favorable, then just include the list name. If the reviewer is not a member of the project, provide the name, email, and if ports an external role like maintainer: Reviewed by a developer: [source,shell] .... Reviewed by: username .... Reviewed by a ports maintainer that is not a developer: [source,shell] .... Reviewed by: Full Name (maintainer) .... |`Tested by:` |The name and e-mail address of the person or people that tested the change; for developers, just the username on the FreeBSD cluster. |`Discussed with:` |The name and e-mail address of the person or people that contributed to the patch by providing meaningful feedback; for developers, just the username on the FreeBSD cluster. Typically used to credit those who did not explicitly review, test, or approve the change, but nevertheless contributed to the discussion surrounding the change, which led to improvements and a better understanding of its impact on the FreeBSD project. |`Approved by:` a| The name and e-mail address of the person or people that approved the change; for developers, just the username on the FreeBSD cluster. There are several cases where approval is customary: * while a new committer is under mentorship * commits to an area of the tree covered by the LOCKS file (src) * during a release cycle * committing non-obvious changes to a repo where you do not hold a commit bit (e.g. src committer committing to docs); for obvious fixes, `Reviewed by:` is sufficient * committing to a port maintained by someone else While under mentorship, get mentor approval before the commit. Enter the mentor's username in this field, and note that they are a mentor: [source,shell] .... Approved by: username-of-mentor (mentor) .... If a team approved these commits then include the team name followed by the username of the approver in parentheses. For example: [source,shell] .... Approved by: re (username) .... |`Obtained from:` |The name of the project (if any) from which the code was obtained. Do not use this line for the name of an individual person. |`Fixes:` |The Git short hash and the title line of a commit that is fixed by this change as returned by `git log -n1 --format='%h ("%s")' GIT-COMMIT-HASH`. We include the commit title so that the referenced commit can be located even in the case that a future VCS migration invalidates hash references. |`MFC after:` |To receive an e-mail reminder to MFC at a later date, specify the number of days, weeks, or months after which an MFC is planned. |`MFC to:` |If the commit should be merged to a subset of stable branches, specify the branch names. |`MFH:` |If the commit is to be merged into a ports quarterly branch name, specify the quarterly branch. For example `2021Q2`. |`Relnotes:` |If the change is a candidate for inclusion in the release notes for the next release from the branch, set to `yes`. |Candidates are user-visible changes, new features, compatibility breaks, etc.. |If you forget to set this line, or want to provide more details, add an entry to the `RELNOTES` file in the root of the src tree. |The `RELNOTES` file is used to generate release notes for the next release. |Do not use the `Relnotes:` line to describe the change: its only valid value is `yes`. |`Security:` |If the change is related to a security vulnerability or security exposure, include one or more references or a description of the issue. If possible, include a VuXML URL or a CVE ID. |`Event:` |The description for the event where this commit was made. If this is a recurring event, add the year or even the month to it. For example, this could be `FooBSDcon 2019`. The idea behind this line is to put recognition to conferences, gatherings, and other types of meetups and to show that these are useful to have. Please do not use the `Sponsored by:` line for this as that is meant for organizations sponsoring certain features or developers working on them. |`Sponsored by:` |Sponsoring organizations for this change, if any. Separate multiple organizations with commas. If only a portion of the work was sponsored, or different amounts of sponsorship were provided to different authors, please give appropriate credit in parentheses after each sponsor name. For example, `Example.com (alice, code refactoring), Wormulon (bob), Momcorp (cindy)` shows that Alice was sponsored by Example.com to do code refactoring, while Wormulon sponsored Bob's work and Momcorp sponsored Cindy's work. Other authors were either not sponsored or chose not to list sponsorship. |`Pull Request:` |This change was submitted as a pull request or merge request against one of FreeBSD's public read-only Git repositories. It should include the entire URL to the pull request, as these often act as code reviews for the code. For example: `https://github.com/freebsd/freebsd-src/pull/745` | `Closes:` | This change concludes the patch series discussed at the specified Github pull request, and closes that request. It should include the entire URL to the pull request, as these often act as code reviews for the code. For example: `https://github.com/freebsd/freebsd-src/pull/745` |`Co-authored-by:` |The name and email address of an additional author of the commit. GitHub has a detailed description of the Co-authored-by trailer at https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors. |`Signed-off-by:` |ID certifies compliance with https://developercertificate.org/ |`Differential Revision:` |The full URL of the Phabricator review. This line __must be the last line__. For example: `https://reviews.freebsd.org/D1708`. |=== .Commit Log for a Commit Based on a PR [example] ==== The commit is based on a patch from a PR submitted by John Smith. The commit message "PR" field is filled. [.programlisting] .... ... PR: 12345 .... The committer sets the author of the patch with `git commit --author "John Smith "`. ==== .Commit Log for a Commit Needing Review [example] ==== The virtual memory system is being changed. After posting patches to the appropriate mailing list (in this case, `freebsd-arch`) and the changes have been approved. [.programlisting] .... ... Reviewed by: -arch .... ==== .Commit Log for a Commit Needing Approval [example] ==== Commit a port, after working with the listed MAINTAINER, who said to go ahead and commit. [.programlisting] .... ... Approved by: abc (maintainer) .... Where _abc_ is the account name of the person who approved. ==== .Commit Log for a Commit Bringing in Code from OpenBSD [example] ==== Committing some code based on work done in the OpenBSD project. [.programlisting] .... ... Obtained from: OpenBSD .... ==== .Commit Log for a Change to FreeBSD-CURRENT with a Planned Commit to FreeBSD-STABLE to Follow at a Later Date. [example] ==== Committing some code which will be merged from FreeBSD-CURRENT into the FreeBSD-STABLE branch after two weeks. [.programlisting] .... ... MFC after: 2 weeks .... Where _2_ is the number of days, weeks, or months after which an MFC is planned. The _weeks_ option may be `day`, `days`, `week`, `weeks`, `month`, `months`. ==== It is often necessary to combine these. Consider the situation where a user has submitted a PR containing code from the NetBSD project. Looking at the PR, the developer sees it is not an area of the tree they normally work in, so they have the change reviewed by the `arch` mailing list. Since the change is complex, the developer opts to MFC after one month to allow adequate testing. The extra information to include in the commit would look something like .Example Combined Commit Log [example] ==== [.programlisting] .... PR: 54321 Reviewed by: -arch Obtained from: NetBSD MFC after: 1 month Relnotes: yes .... ==== [[pref-license]] == Preferred License for New Files The FreeBSD Project's full license policy is documented in the extref:{license-guide}[FreeBSD License Policies] article. The rest of this section is intended to help you get started. As a rule, when in doubt, ask. It is much easier to give advice than to fix the source tree. SPDX-only license marking is strongly preferred. The FreeBSD Project uses this text as the preferred license: [.programlisting] .... /* * Copyright (c) [year] [your name] * * SPDX-License-Identifier: BSD-2-Clause */ .... The preferred order is the copyright notice first, followed by the SPDX-License-Identifier, but either order is acceptable. New contributions to FreeBSD should use the BSD-2-Clause license. The FreeBSD project does not allow the "advertising clause" in new code. If you have code in the tree with the advertising clause, please consider switching to a license without it. The FreeBSD project discourages completely new licenses and variations on the standard licenses. New licenses require the approval of {core-email}. Project policy dictates that code under some non-BSD licenses must be placed only in specific sections of the repository, and in some cases, compilation must be conditional or even disabled by default. For example, the GENERIC kernel must be compiled under only licenses identical to or substantially similar to the BSD license. GPL, APSL, CDDL, etc, licensed software must not be compiled into GENERIC. Developers are reminded that in open source, getting "open" right is just as important as getting "source" right, as improper handling of intellectual property has serious consequences. Any questions or concerns should immediately be brought to the attention of the core team. [[tracking.license.grants]] == Keeping Track of Licenses Granted to the FreeBSD Project Various software or data exist in the repositories where the FreeBSD project has been granted a special license to be able to use them. A case in point are the Terminus fonts for use with man:vt[4]. Here the author Dimitar Zhekov has allowed us to use the "Terminus BSD Console" font under a 2-clause BSD license rather than the regular Open Font License he normally uses. It is clearly sensible to keep a record of any such license grants. To that end, the {core-email} has decided to keep an archive of them. Whenever the FreeBSD project is granted a special license we require the {core-email} to be notified. Any developers involved in arranging such a license grant, please send details to the {core-email} including: * Contact details for people or organizations granting the special license. * What files, directories etc. in the repositories are covered by the license grant including the revision numbers where any specially licensed material was committed. * The date the license comes into effect from. Unless otherwise agreed, this will be the date the license was issued by the authors of the software in question. * The license text. * A note of any restrictions, limitations or exceptions that apply specifically to FreeBSD's usage of the licensed material. * Any other relevant information. Once the {core-email} is satisfied that all the necessary details have been gathered and are correct, the secretary will send a PGP-signed acknowledgment of receipt including the license details. This receipt will be persistently archived and serve as our permanent record of the license grant. The license archive should contain only details of license grants; this is not the place for any discussions around licensing or other subjects. Access to data within the license archive will be available on request to the {core-email}. [[spdx.tags]] == SPDX Tags in the tree The project uses https://spdx.dev[SPDX] tags in our source base. SPDX-only license marking (without reproducing the full license text) is strongly preferred for new files. When a file contains only a copyright notice and an SPDX-License-Identifier tag, the SPDX tag specifies the license for that file. When a file contains both an SPDX-License-Identifier tag and the full verbatim license text, the SPDX tag is informative and the verbatim license is controlling in the event of a discrepancy. The project draws identifiers from SPDX's list of valid https://spdx.org/licenses/[short license identifiers] and uses only the _SPDX-License-Identifier_ tag. See the extref:{license-guide}[FreeBSD License Policies] article for the full specification of how SPDX expressions are used in the FreeBSD software collection. [[developer.relations]] == Developer Relations When working directly on your own code or on code which is already well established as your responsibility, then there is probably little need to check with other committers before jumping in with a commit. When working on a bug in an area of the system which is clearly orphaned (and there are a few such areas, to our shame), the same applies. When modifying parts of the system which are maintained, formally or informally, consider asking for a review just as a developer would have before becoming a committer. For ports, contact the listed `MAINTAINER` in the [.filename]#Makefile#. To determine if an area of the tree is maintained, check the MAINTAINERS file at the root of the tree. If nobody is listed, scan the revision history to see who has committed changes in the past. To list the names and email addresses of all commit authors for a given file in the last 2 years and the number of commits each has authored, ordered by descending number of commits, use: [source,shell] ---- % git -C /path/to/repo shortlog -sne --since="2 years" -- relative/path/to/file ---- If queries go unanswered or the committer otherwise indicates a lack of interest in the area affected, go ahead and commit it. [IMPORTANT] ==== Avoid sending private emails to maintainers. Other people might be interested in the conversation, not just the final output. ==== If there is any doubt about a commit for any reason at all, have it reviewed before committing. Better to have it flamed then and there rather than when it is part of the repository. If a commit does results in controversy erupting, it may be advisable to consider backing the change out again until the matter is settled. Remember, with a version control system we can always change it back. Do not impugn the intentions of others. If they see a different solution to a problem, or even a different problem, it is probably not because they are stupid, because they have questionable parentage, or because they are trying to destroy hard work, personal image, or FreeBSD, but basically because they have a different outlook on the world. Different is good. Disagree honestly. Argue your position from its merits, be honest about any shortcomings it may have, and be open to seeing their solution, or even their vision of the problem, with an open mind. Accept correction. We are all fallible. When you have made a mistake, apologize and get on with life. Do not beat up yourself, and certainly do not beat up others for your mistake. Do not waste time on embarrassment or recrimination, just fix the problem and move on. Ask for help. Seek out (and give) peer reviews. One of the ways open source software is supposed to excel is in the number of eyeballs applied to it; this does not apply if nobody will review code. [[if-in-doubt]] == If in Doubt... When unsure about something, whether it be a technical issue or a project convention be sure to ask. If you stay silent you will never make progress. If it relates to a technical issue ask on the public mailing lists. Avoid the temptation to email the individual person that knows the answer. This way everyone will be able to learn from the question and the answer. For project specific or administrative questions ask, in order: * Your mentor or former mentor. * An experienced committer on IRC, email, etc. * Any team with a "hat", as they can give you a definitive answer. * If still not sure, ask on {developers-name}. Once your question is answered, if no one pointed you to documentation that spelled out the answer to your question, document it, as others will have the same question. [[bugzilla]] == Bugzilla The FreeBSD Project utilizes Bugzilla for tracking bugs and change requests. If you commit a fix or suggestion found in the PR database, be sure to close the PR. It is also considered nice if you take time to close any other PRs associated with your commits. Committers with non-``FreeBSD.org`` Bugzilla accounts can have the old account merged with the `FreeBSD.org` account by following these steps: [.procedure] ==== . Log in using your old account. . Open new bug. Choose `Services` as the Product, and `Bug Tracker` as the Component. In bug description list accounts you wish to be merged. . Log in using `FreeBSD.org` account and post comment to newly opened bug to confirm ownership. See crossref:committers-guide[kerberos-ldap, Kerberos and LDAP web Password for FreeBSD Cluster] for more details on how to generate or set a password for your `FreeBSD.org` account. . If there are more than two accounts to merge, post comments from each of them. ==== You can find out more about Bugzilla at: * extref:{pr-guidelines}[FreeBSD Problem Report Handling Guidelines] * link:https://www.FreeBSD.org/support/[https://www.FreeBSD.org/support] [[phabricator]] == Phabricator The FreeBSD Project utilizes https://reviews.freebsd.org[Phabricator] for code review requests. See the https://wiki.freebsd.org/Phabricator[Phabricator wiki page] for details. Please use the `git arc` command provided by `devel/freebsd-git-arc` (install the port or package, then type `git help arc` for documentation) to create and update Phabricator reviews. This will make it easier for others to review and test your patches. Committers with non-``FreeBSD.org`` Phabricator accounts can have the old account renamed to the ``FreeBSD.org`` account by following these steps: [.procedure] ==== . Change your Phabricator account email to your `FreeBSD.org` email. . Open new bug on our bug tracker using your `FreeBSD.org` account, see crossref:committers-guide[bugzilla, Bugzilla] for more information. Choose `Services` as the Product, and `Code Review` as the Component. In bug description request that your Phabricator account be renamed, and provide a link to your Phabricator user. For example, `https://reviews.freebsd.org/p/bob_example.com/` ==== [IMPORTANT] ==== Phabricator accounts cannot be merged, please do not open a new account. ==== [[people]] == Who's Who Besides the repository meisters, there are other FreeBSD project members and teams whom you will probably get to know in your role as a committer. Briefly, and by no means all-inclusively, these are: `{doceng}`:: doceng is the group responsible for the documentation build infrastructure, approving new documentation committers, and ensuring that the FreeBSD website and documentation on the FTP site is up to date with respect to the Subversion tree. It is not a conflict resolution body. The vast majority of documentation related discussion takes place on the {freebsd-doc}. More details regarding the doceng team can be found in its https://www.FreeBSD.org/internal/doceng/[charter]. Committers interested in contributing to the documentation should familiarize themselves with the extref:{fdp-primer}[Documentation Project Primer]. `{re-members}`:: These are the members of the `{re}`. This team is responsible for setting release deadlines and controlling the release process. During code freezes, the release engineers have final authority on all changes to the system for whichever branch is pending release status. If there is something you want merged from FreeBSD-CURRENT to FreeBSD-STABLE (whatever values those may have at any given time), these are the people to talk to about it. `{so}`:: `{so-name}` is the link:https://www.FreeBSD.org/security/[FreeBSD Security Officer] and oversees the `{security-officer}`. {committers-name}:: {dev-src-all}, {dev-ports-all} and {dev-doc-all} are the mailing lists that the version control system uses to send commit messages to. _Never_ send email directly to these lists. Only send replies to this list when they are short and are directly related to a commit. {developers-name}:: All committers are subscribed to -developers. This list was created to be a forum for the committers "community" issues. Examples are Core voting, announcements, etc. + The {developers-name} is for the exclusive use of FreeBSD committers. To develop FreeBSD, committers must have the ability to openly discuss matters that will be resolved before they are publicly announced. Frank discussions of work in progress are not suitable for open publication and may harm FreeBSD. + All FreeBSD committers are expected not to not publish or forward messages from the {developers-name} outside the list membership without permission of all of the authors. Violators will be removed from the {developers-name}, resulting in a suspension of commit privileges. Repeated or flagrant violations may result in permanent revocation of commit privileges. + This list is _not_ intended as a place for code reviews or for any technical discussion. In fact using it as such hurts the FreeBSD Project as it gives a sense of a closed list where general decisions affecting all of the FreeBSD using community are made without being "open". Last, but not least __never, never ever, email the {developers-name} and CC:/BCC: another FreeBSD list__. Never, ever email another FreeBSD email list and CC:/BCC: the {developers-name}. Doing so can greatly diminish the benefits of this list. [[ssh.guide]] == SSH Quick-Start Guide [.procedure] ==== . If you do not wish to type your password in every time you use man:ssh[1], and you use keys to authenticate, man:ssh-agent[1] is there for your convenience. If you want to use man:ssh-agent[1], make sure that you run it before running other applications. X users, for example, usually do this from their [.filename]#.xsession# or [.filename]#.xinitrc#. See man:ssh-agent[1] for details. . Generate a key pair using man:ssh-keygen[1]. The key pair will wind up in your [.filename]#$HOME/.ssh/# directory. + [IMPORTANT] ====== Only ECDSA, Ed25519 or RSA keys are supported. ====== . Send your public key ([.filename]#$HOME/.ssh/id_ecdsa.pub#, [.filename]#$HOME/.ssh/id_ed25519.pub#, or [.filename]#$HOME/.ssh/id_rsa.pub#) to the person setting you up as a committer so it can be put into [.filename]#yourlogin# in [.filename]#/etc/ssh-keys/# on `freefall`. ==== Now man:ssh-add[1] can be used for authentication once per session. It prompts for the private key's pass phrase, and then stores it in the authentication agent (man:ssh-agent[1]). Use `ssh-add -d` to remove keys stored in the agent. Test with a simple remote command: `ssh freefall.FreeBSD.org ls /usr`. For more information, see package:security/openssh-portable[], man:ssh[1], man:ssh-add[1], man:ssh-agent[1], man:ssh-keygen[1], and man:scp[1]. For information on adding, changing, or removing man:ssh[1] keys, see https://wiki.freebsd.org/clusteradm/ssh-keys[this article]. [[coverity]] == Coverity(R) Availability for FreeBSD Committers All FreeBSD developers can obtain access to Coverity analysis results of all FreeBSD Project software. All who are interested in obtaining access to the analysis results of the automated Coverity runs, can sign up at http://scan.coverity.com/[Coverity Scan]. The FreeBSD wiki includes a mini-guide for developers who are interested in working with the Coverity(R) analysis reports: https://wiki.freebsd.org/CoverityPrevent[https://wiki.freebsd.org/CoverityPrevent]. Please note that this mini-guide is only readable by FreeBSD developers, so if you cannot access this page, you will have to ask someone to add you to the appropriate Wiki access list. Finally, all FreeBSD developers who are going to use Coverity(R) are always encouraged to ask for more details and usage information, by posting any questions to the mailing list of the FreeBSD developers. [[rules]] == The FreeBSD Committers' Big List of Rules Everyone involved with the FreeBSD project is expected to abide by the _Code of Conduct_ available from link:https://www.FreeBSD.org/internal/code-of-conduct/[https://www.FreeBSD.org/internal/code-of-conduct]. As committers, you form the public face of the project, and how you behave has a vital impact on the public perception of it. This guide expands on the parts of the _Code of Conduct_ specific to committers. . Respect other committers. . Respect other contributors. . Discuss any significant change _before_ committing. . Respect existing maintainers (if listed in the `MAINTAINER` field in [.filename]#Makefile# or in [.filename]#MAINTAINER# in the top-level directory). . Any disputed change must be backed out pending resolution of the dispute if requested by a maintainer. Security related changes may override a maintainer's wishes at the Security Officer's discretion. . Changes go to FreeBSD-CURRENT before FreeBSD-STABLE unless specifically permitted by the release engineer or unless they are not applicable to FreeBSD-CURRENT. Any non-trivial or non-urgent change which is applicable should also be allowed to sit in FreeBSD-CURRENT for at least 3 days before merging so that it can be given sufficient testing. The release engineer has the same authority over the FreeBSD-STABLE branch as outlined for the maintainer in rule #5. . Do not fight in public with other committers; it looks bad. . Respect all code freezes and read the `committers` and `developers` mailing lists in a timely manner so you know when a code freeze is in effect. . When in doubt on any procedure, ask first! . Test your changes before committing them. . Do not commit to contributed software without _explicit_ approval from the respective maintainers. As noted, breaking some of these rules can be grounds for suspension or, upon repeated offense, permanent removal of commit privileges. Individual members of core have the power to temporarily suspend commit privileges until core as a whole has the chance to review the issue. In case of an "emergency" (a committer doing damage to the repository), a temporary suspension may also be done by the repository meisters. Only a 2/3 majority of core has the authority to suspend commit privileges for longer than a week or to remove them permanently. This rule does not exist to set core up as a bunch of cruel dictators who can dispose of committers as casually as empty soda cans, but to give the project a kind of safety fuse. If someone is out of control, it is important to be able to deal with this immediately rather than be paralyzed by debate. In all cases, a committer whose privileges are suspended or revoked is entitled to a "hearing" by core, the total duration of the suspension being determined at that time. A committer whose privileges are suspended may also request a review of the decision after 30 days and every 30 days thereafter (unless the total suspension period is less than 30 days). A committer whose privileges have been revoked entirely may request a review after a period of 6 months has elapsed. This review policy is _strictly informal_ and, in all cases, core reserves the right to either act on or disregard requests for review if they feel their original decision to be the right one. In all other aspects of project operation, core is a subset of committers and is bound by the __same rules__. Just because someone is in core this does not mean that they have special dispensation to step outside any of the lines painted here; core's "special powers" only kick in when it acts as a group, not on an individual basis. As individuals, the core team members are all committers first and core second. === Details [[respect]] . Respect other committers. + This means that you need to treat other committers as the peer-group developers that they are. Despite our occasional attempts to prove the contrary, one does not get to be a committer by being stupid and nothing rankles more than being treated that way by one of your peers. Whether we always feel respect for one another or not (and everyone has off days), we still have to _treat_ other committers with respect at all times, on public forums and in private email. + Being able to work together long term is this project's greatest asset, one far more important than any set of changes to the code, and turning arguments about code into issues that affect our long-term ability to work harmoniously together is just not worth the trade-off by any conceivable stretch of the imagination. + To comply with this rule, do not send email when you are angry or otherwise behave in a manner which is likely to strike others as needlessly confrontational. First calm down, then think about how to communicate in the most effective fashion for convincing the other persons that your side of the argument is correct, do not just blow off some steam so you can feel better in the short term at the cost of a long-term flame war. Not only is this very bad "energy economics", but repeated displays of public aggression which impair our ability to work well together will be dealt with severely by the project leadership and may result in suspension or termination of your commit privileges. The project leadership will take into account both public and private communications brought before it. It will not seek the disclosure of private communications, but it will take it into account if it is volunteered by the committers involved in the complaint. + All of this is never an option which the project's leadership enjoys in the slightest, but unity comes first. No amount of code or good advice is worth trading that away. . Respect other contributors. + You were not always a committer. At one time you were a contributor. Remember that at all times. Remember what it was like trying to get help and attention. Do not forget that your work as a contributor was very important to you. Remember what it was like. Do not discourage, belittle, or demean contributors. Treat them with respect. They are our committers in waiting. They are every bit as important to the project as committers. Their contributions are as valid and as important as your own. After all, you made many contributions before you became a committer. Always remember that. + Consider the points raised under crossref:committers-guide[respect,Respect other committers] and apply them also to contributors. . Discuss any significant change _before_ committing. + The repository is not where changes are initially submitted for correctness or argued over, that happens first in the mailing lists or by use of the Phabricator service. The commit will only happen once something resembling consensus has been reached. This does not mean that permission is required before correcting every obvious syntax error or manual page misspelling, just that it is good to develop a feel for when a proposed change is not quite such a no-brainer and requires some feedback first. People really do not mind sweeping changes if the result is something clearly better than what they had before, they just do not like being _surprised_ by those changes. The very best way of making sure that things are on the right track is to have code reviewed by one or more other committers. + When in doubt, ask for review! . Respect existing maintainers if listed. + Many parts of FreeBSD are not "owned" in the sense that any specific individual will jump up and yell if you commit a change to "their" area, but it still pays to check first. One convention we use is to put a maintainer line in the [.filename]#Makefile# for any package or subtree which is being actively maintained by one or more people; see extref:{developers-handbook}policies[Source Tree Guidelines and Policies, policies] for documentation on this. Where sections of code have several maintainers, commits to affected areas by one maintainer need to be reviewed by at least one other maintainer. In cases where the "maintainer-ship" of something is not clear, look at the repository logs for the files in question and see if someone has been working recently or predominantly in that area. . Any disputed change must be backed out pending resolution of the dispute if requested by a maintainer. Security related changes may override a maintainer's wishes at the Security Officer's discretion. + This may be hard to swallow in times of conflict (when each side is convinced that they are in the right, of course) but a version control system makes it unnecessary to have an ongoing dispute raging when it is far easier to simply reverse the disputed change, get everyone calmed down again and then try to figure out what is the best way to proceed. If the change turns out to be the best thing after all, it can be easily brought back. If it turns out not to be, then the users did not have to live with the bogus change in the tree while everyone was busily debating its merits. People _very_ rarely call for back-outs in the repository since discussion generally exposes bad or controversial changes before the commit even happens, but on such rare occasions the back-out should be done without argument so that we can get immediately on to the topic of figuring out whether it was bogus or not. . Changes go to FreeBSD-CURRENT before FreeBSD-STABLE unless specifically permitted by the release engineer or unless they are not applicable to FreeBSD-CURRENT. Any non-trivial or non-urgent change which is applicable should also be allowed to sit in FreeBSD-CURRENT for at least 3 days before merging so that it can be given sufficient testing. The release engineer has the same authority over the FreeBSD-STABLE branch as outlined in rule #5. + This is another "do not argue about it" issue since it is the release engineer who is ultimately responsible (and gets beaten up) if a change turns out to be bad. Please respect this and give the release engineer your full cooperation when it comes to the FreeBSD-STABLE branch. The management of FreeBSD-STABLE may frequently seem to be overly conservative to the casual observer, but also bear in mind the fact that conservatism is supposed to be the hallmark of FreeBSD-STABLE and different rules apply there than in FreeBSD-CURRENT. There is also really no point in having FreeBSD-CURRENT be a testing ground if changes are merged over to FreeBSD-STABLE immediately. Changes need a chance to be tested by the FreeBSD-CURRENT developers, so allow some time to elapse before merging unless the FreeBSD-STABLE fix is critical, time sensitive or so obvious as to make further testing unnecessary (spelling fixes to manual pages, obvious bug/typo fixes, etc.) In other words, apply common sense. + Changes to the security branches (for example, `releng/9.3`) must be approved by a member of the `{security-officer}`, or in some cases, by a member of the `{re}`. . Do not fight in public with other committers; it looks bad. + This project has a public image to uphold and that image is very important to all of us, especially if we are to continue to attract new members. There will be occasions when, despite everyone's very best attempts at self-control, tempers are lost and angry words are exchanged. The best thing that can be done in such cases is to minimize the effects of this until everyone has cooled back down. Do not air angry words in public and do not forward private correspondence or other private communications to public mailing lists, mail aliases, instant messaging channels or social media sites. What people say one-to-one is often much less sugar-coated than what they would say in public, and such communications therefore have no place there - they only serve to inflame an already bad situation. If the person sending a flame-o-gram at least had the grace to send it privately, then have the grace to keep it private yourself. If you feel you are being unfairly treated by another developer, and it is causing you anguish, bring the matter up with core rather than taking it public. Core will do its best to play peace makers and get things back to sanity. In cases where the dispute involves a change to the codebase and the participants do not appear to be reaching an amicable agreement, core may appoint a mutually-agreeable third party to resolve the dispute. All parties involved must then agree to be bound by the decision reached by this third party. . Respect all code freezes and read the `committers` and `developers` mailing list on a timely basis so you know when a code freeze is in effect. + Committing unapproved changes during a code freeze is a really big mistake and committers are expected to keep up-to-date on what is going on before jumping in after a long absence and committing 10 megabytes worth of accumulated stuff. People who abuse this on a regular basis will have their commit privileges suspended until they get back from the FreeBSD Happy Reeducation Camp we run in Greenland. . When in doubt on any procedure, ask first! + Many mistakes are made because someone is in a hurry and just assumes they know the right way of doing something. If you have not done it before, chances are good that you do not actually know the way we do things and really need to ask first or you are going to completely embarrass yourself in public. There is no shame in asking "how in the heck do I do this?" We already know you are an intelligent person; otherwise, you would not be a committer. . Test your changes before committing them. + If your changes are to the kernel, make sure you can still compile both GENERIC and LINT. If your changes are anywhere else, make sure you can still compile userspace via `make buildworld`. If your changes are to a branch, make sure your testing occurs with a machine which is running that code. If you have a change which also may break another architecture, be sure and test on all supported architectures. Please ensure your change works for crossref:committers-guide[compilers,supported toolchains]. Please refer to the https://www.FreeBSD.org/internal/[FreeBSD Internal Page] for a list of available resources. As other architectures are added to the FreeBSD supported platforms list, the appropriate shared testing resources will be made available. . Do not commit to contributed software without _explicit_ approval from the respective maintainers. + Contributed software is anything under the [.filename]#src/contrib#, [.filename]#src/crypto#, or [.filename]#src/sys/contrib# trees. + The trees mentioned above are for contributed software usually imported onto a vendor branch. Committing something there may cause unnecessary headaches when importing newer versions of the software. As a general consider sending patches upstream to the vendor. Patches may be committed to FreeBSD first with permission of the maintainer. + Reasons for modifying upstream software range from wanting strict control over a tightly coupled dependency to lack of portability in the canonical repository's distribution of their code. Regardless of the reason, effort to minimize the maintenance burden of fork is helpful to fellow maintainers. Avoid committing trivial or cosmetic changes to files since it makes every merge thereafter more difficult: such patches need to be manually re-verified every import. + If a particular piece of software lacks a maintainer, you are encouraged to take up ownership. If you are unsure of the current maintainership email {freebsd-arch} and ask. === Policy on Multiple Architectures In an effort to make it easier to keep FreeBSD portable across the platforms we support, core has developed this mandate: [.blockquote] Major design work (including major API and ABI changes) must prove itself on at least one Tier 1 platform before it may be committed to the source tree. Developers should also be aware of our Tier Policy for the long term support of hardware architectures. The rules here are intended to provide guidance during the development process, and are distinct from the requirements for features and architectures listed in that section. The Tier rules for feature support on architectures at release-time are more strict than the rules for changes during the development process. [[compilers]] === Policy on Multiple Compilers The FreeBSD base system builds with both Clang and GCC. The project does this in a careful and controlled way to maximize benefits from this extra work, while keeping the extra work to a minimum. Supporting both Clang and GCC improves the flexibility our users have. These compilers have different strengths and weaknesses, and supporting both allows users to pick the best one for their needs. Clang and GCC support similar dialects of C and C++, necessitating a relatively small amount of conditional code. The project gains increased code coverage and improves the code quality by using features from both compilers. The project is able to build in more user environments and leverage more CI environments by supporting this range, increasing convenience for users and giving them more tools to test with. By carefully constraining the range of versions supported to modern versions of these compilers, the project avoids unduly increasing the testing matrix. Older and obscure compilers, as well as older dialects of the languages, have extremely limited support that allow user programs to build with them, but without constraining the base system to being built with them. The exact balance continues to evolve to ensure the benefits of extra work remain greater than the burdens it imposes. The project used to support really old Intel compilers or old GCC versions, but we traded supporting those obsolete compilers for a carefully selected range of modern compilers. This section documents where we use different compilers, and the expectations around that. The FreeBSD base system includes an in-tree Clang compiler. Due to being in the tree, this compiler is the most supported compiler. All changes must compile with it, prior to commit. Complete testing, as appropriate for the change, should be done with this compiler. The FreeBSD base system also supports various versions of Clang and GCC as out-of-tree compilers. For large or risky changes, committers should do a test build with a supported version of GCC. Out of tree compilers are available as packages. GCC compilers are available as `${TARGET_ARCH}-gcc${VERSION}` packages, such as package:devel/freebsd-gcc14@aarch64[aarch64-gcc14]. Clang compilers are available as `llvm${VERSION}` packages, such as package:devel/llvm18[llvm18]. The project runs automated CI jobs to build everything with these compilers. Committers are expected to fix the jobs they break with their changes. Committers may test builds of userspace or individual kernels by setting `CROSS_TOOLCHAIN` to the package name, for example `CROSS_TOOLCHAIN=aarch64-gcc14` or `CROSS_TOOLCHAIN=llvm18`. For universe or tinderbox builds, `USE_GCC_TOOLCHAINS=gcc${VERSION}` builds all architectures using the appropriate GCC compiler packages. For universe or tinderbox builds using an out-of-tree Clang, pass `CROSS_TOOLCHAIN=llvm${VERSION}`. Note that while all architectures in the base system can be compiled by Clang, only a few architectures can be fully built by GCC. The FreeBSD project also has some CI pipelines on github. For pull requests on github and some branches pushed to github forks, a number of cross compilation jobs run. These test FreeBSD building using versions of Clang that lag the in-tree compiler by one or more major versions. The FreeBSD project is also upgrading compilers. Both Clang and GCC are fast moving targets. Some work to change things in the tree, for example removing the old-style K&R function declarations and definitions, will land in the tree prior to the compiler landing. Committers should try to be mindful about this and be receptive to looking into problems with their code or changes with these new compilers. Also, just after a new compiler version hits the tree, people may need to compile things with the old version if there was an undetected regression suspected. In addition to the compiler, LLVM's LLD and GNU's binutils are used indirectly by the compiler. Committers should be mindful of variations in assembler syntax and features of the linkers and ensure both variants work. These components will be tested as part of FreeBSD's CI jobs for Clang or GCC. The FreeBSD project provides headers and libraries that allow other compilers to be used to build software not in the base system. These headers have support for making the environment as strict as the standard, supporting prior dialects of ANSI-C back to C89, and other edge cases our large ports collection has uncovered. This support constrains retirement of older standards in places like header files, but does not constrain updating the base system to newer dialects. Nor does it require the base system to compile with these older standards as a whole. Breaking this support will cause packages in the ports collection to fail, so should be avoided where possible, and promptly fixed when it is easy to do so. The FreeBSD build system currently accommodates these different environments. As new warnings are added to compilers, the project tries to fix them. However, sometimes these warnings require extensive rework, so are suppressed in some way by using make variables that evaluate to the proper thing depending on the compiler version. Developers should be mindful of this, and ensure any compiler specific flags are properly conditionalized. ==== Current Compiler Versions The versions of supported compilers for a given branch such as `main` or `stable/X` varies over time. The authoritative source for supported compiler versions are automated CI jobs tested in GitHub's cross-build actions and Jenkins. [.tblbasic] [cols="12*",options="header",] |=== |Branch | In-tree Compiler |llvm12 | llvm13 | llvm14 | llvm15 | llvm18 |amd64-gcc12 | amd64-gcc13 | amd64-gcc14 | amd64-gcc15 |riscv64-gcc15 |main | llvm 19 | | | | Y | Y | Y | Y | Y | Y | Y |stable/15 | llvm 19 | | | Y | | Y | Y | Y | Y | | |stable/14 | llvm 19 | Y | Y | Y | | | Y | | Y | | |stable/13 | llvm 19 | Y | Y | Y | | | Y | | Y | | |=== GCC toolchains are tested for amd64 and riscv64 via CI jobs in Jenkins. LLVM toolchains are tested for aarch64 and amd64 in GitHub's cross-build actions. === Other Suggestions When committing documentation changes, use a spell checker before committing. For all XML docs, verify that the formatting directives are correct by running `make lint` and package:textproc/igor[]. For manual pages, run package:sysutils/manck[] and package:textproc/igor[] over the manual page to verify all of the cross references and file references are correct and that the man page has all of the appropriate `MLINKS` installed. Do not mix style fixes with new functionality. A style fix is any change which does not modify the functionality of the code. Mixing the changes obfuscates the functionality change when asking for differences between revisions, which can hide any new bugs. Do not include whitespace changes with content changes in commits to [.filename]#doc/#. The extra clutter in the diffs makes the translators' job much more difficult. Instead, make any style or whitespace changes in separate commits that are clearly labeled as such in the commit message. === Deprecating Features When it is necessary to remove functionality from software in the base system, follow these guidelines whenever possible: . Mention is made in the manual page and possibly the release notes that the option, utility, or interface is deprecated. Use of the deprecated feature generates a warning. . The option, utility, or interface is preserved until the next major (point zero) release. . The option, utility, or interface is removed and no longer documented. It is now obsolete. It is also generally a good idea to note its removal in the release notes. === Privacy and Confidentiality . Most FreeBSD business is done in public. + FreeBSD is an _open_ project. Which means that not only can anyone use the source code, but that most of the development process is open to public scrutiny. . Certain sensitive matters must remain private or held under embargo. + There unfortunately cannot be complete transparency. As a FreeBSD developer you will have a certain degree of privileged access to information. Consequently you are expected to respect certain requirements for confidentiality. Sometimes the need for confidentiality comes from external collaborators or has a specific time limit. Mostly though, it is a matter of not releasing private communications. . The Security Officer has sole control over the release of security advisories. + Where there are security problems that affect many different operating systems, FreeBSD frequently depends on early access to be able to prepare advisories for coordinated release. Unless FreeBSD developers can be trusted to maintain security, such early access will not be made available. The Security Officer is responsible for controlling pre-release access to information about vulnerabilities, and for timing the release of all advisories. He may request help under condition of confidentiality from any developer with relevant knowledge to prepare security fixes. . Communications with Core are kept confidential for as long as necessary. + Communications to core will initially be treated as confidential. Eventually however, most of Core's business will be summarized into the monthly or quarterly core reports. Care will be taken to avoid publicising any sensitive details. Records of some particularly sensitive subjects may not be reported on at all and will be retained only in Core's private archives. . Non-disclosure Agreements may be required for access to certain commercially sensitive data. + Access to certain commercially sensitive data may only be available under a Non-Disclosure Agreement. The FreeBSD Foundation legal staff must be consulted before any binding agreements are entered into. . Private communications must not be made public without permission. + Beyond the specific requirements above there is a general expectation not to publish private communications between developers without the consent of all parties involved. Ask permission before forwarding a message onto a public mailing list, or posting it to a forum or website that can be accessed by other than the original correspondents. . Communications on project-only or restricted access channels must be kept private. + Similarly to personal communications, certain internal communications channels, including FreeBSD Committer only mailing lists and restricted access IRC channels are considered private communications. Permission is required to publish material from these sources. . Core may approve publication. + Where it is impractical to obtain permission due to the number of correspondents or where permission to publish is unreasonably withheld, Core may approve release of such private matters that merit more general publication. [[archs]] == Support for Multiple Architectures FreeBSD is a highly portable operating system intended to function on many different types of hardware architectures. Maintaining clean separation of Machine Dependent (MD) and Machine Independent (MI) code, as well as minimizing MD code, is an important part of our strategy to remain agile with regards to current hardware trends. Each new hardware architecture supported by FreeBSD adds substantially to the cost of code maintenance, toolchain support, and release engineering. It also dramatically increases the cost of effective testing of kernel changes. As such, there is strong motivation to differentiate between classes of support for various architectures while remaining strong in a few key architectures that are seen as the FreeBSD "target audience". === Statement of General Intent The FreeBSD Project targets "production quality commercial off-the-shelf (COTS) workstation, server, and high-end embedded systems". By retaining a focus on a narrow set of architectures of interest in these environments, the FreeBSD Project is able to maintain high levels of quality, stability, and performance, as well as minimize the load on various support teams on the project, such as the ports team, documentation team, security officer, and release engineering teams. Diversity in hardware support broadens the options for FreeBSD consumers by offering new features and usage opportunities, but these benefits must always be carefully considered in terms of the real-world maintenance cost associated with additional platform support. The FreeBSD Project differentiates platform targets into four tiers. Each tier includes a list of guarantees consumers may rely on as well as obligations by the Project and developers to fulfill those guarantees. These lists define the minimum guarantees for each tier. The Project and developers may provide additional levels of support beyond the minimum guarantees for a given tier, but such additional support is not guaranteed. Each platform target is assigned to a specific tier for each stable branch. As a result, a platform target might be assigned to different tiers on concurrent stable branches. === Platform Targets Support for a hardware platform consists of two components: kernel support and userland Application Binary Interfaces (ABIs). Kernel platform support includes things needed to run a FreeBSD kernel on a hardware platform such as machine-dependent virtual memory management and device drivers. A userland ABI specifies an interface for user processes to interact with a FreeBSD kernel and base system libraries. A userland ABI includes system call interfaces, the layout and semantics of public data structures, and the layout and semantics of arguments passed to subroutines. Some components of an ABI may be defined by specifications such as the layout of C++ exception objects or calling conventions for C functions. A FreeBSD kernel also uses an ABI (sometimes referred to as the Kernel Binary Interface (KBI)) which includes the semantics and layouts of public data structures and the layout and semantics of arguments to public functions within the kernel itself. A FreeBSD kernel may support multiple userland ABIs. For example, FreeBSD's amd64 kernel supports FreeBSD amd64 and i386 userland ABIs as well as Linux x86_64 and i386 userland ABIs. A FreeBSD kernel should support a "native" ABI as the default ABI. The native "ABI" generally shares certain properties with the kernel ABI such as the C calling convention, sizes of basic types, etc. Tiers are defined for both kernels and userland ABIs. In the common case, a platform's kernel and FreeBSD ABIs are assigned to the same tier. ==== Tier 1: Fully-Supported Architectures Tier 1 platforms are the most mature FreeBSD platforms. They are supported by the security officer, release engineering, and Ports Management Team. Tier 1 architectures are expected to be Production Quality with respect to all aspects of the FreeBSD operating system, including installation and development environments. The FreeBSD Project provides the following guarantees to consumers of Tier 1 platforms: * Official FreeBSD release images will be provided by the release engineering team. * Binary updates and source patches for Security Advisories and Errata Notices will be provided for supported releases. * Source patches for Security Advisories will be provided for supported branches. * Binary updates and source patches for cross-platform Security Advisories will typically be provided at the time of the announcement. * Changes to userland ABIs will generally include compatibility shims to ensure correct operation of binaries compiled against any stable branch where the platform is Tier 1. These shims might not be enabled in the default install. If compatibility shims are not provided for an ABI change, the lack of shims will be clearly documented in the release notes. * Changes to certain portions of the kernel ABI will include compatibility shims to ensure correct operation of kernel modules compiled against the oldest supported release on the branch. Note that not all parts of the kernel ABI are protected. * Official binary packages for third party software will be provided by the ports team. For embedded architectures, these packages may be cross-built from a different architecture. * Most relevant ports should either build or have the appropriate filters to prevent inappropriate ones from building. * New features which are not inherently platform-specific will be fully functional on all Tier 1 architectures. * Features and compatibility shims used by binaries compiled against older stable branches may be removed in newer major versions. Such removals will be clearly documented in the release notes. * Tier 1 platforms should be fully documented. Basic operations will be documented in the FreeBSD Handbook. * Tier 1 platforms will be included in the source tree. * Tier 1 platforms should be self-hosting either via the in-tree toolchain or an external toolchain. If an external toolchain is required, official binary packages for an external toolchain will be provided. To maintain maturity of Tier 1 platforms, the FreeBSD Project will maintain the following resources to support development: * Build and test automation support either in the FreeBSD.org cluster or some other location easily available for all developers. Embedded platforms may substitute an emulator available in the FreeBSD.org cluster for actual hardware. * Inclusion in the `make universe` and `make tinderbox` targets. * Dedicated hardware in one of the FreeBSD clusters for package building (either natively or via qemu-user). Collectively, developers are required to provide the following to maintain the Tier 1 status of a platform: * Changes to the source tree should not knowingly break the build of a Tier 1 platform. * Tier 1 architectures must have a mature, healthy ecosystem of users and active developers. * Developers should be able to build packages on commonly available, non-embedded Tier 1 systems. This can mean either native builds if non-embedded systems are commonly available for the platform in question, or it can mean cross-builds hosted on some other Tier 1 architecture. * Changes cannot break the userland ABI. If an ABI change is required, ABI compatibility for existing binaries should be provided via use of symbol versioning or shared library version bumps. * Changes merged to stable branches cannot break the protected portions of the kernel ABI. If a kernel ABI change is required, the change should be modified to preserve functionality of existing kernel modules. ==== Tier 2: Developmental and Niche Architectures Tier 2 platforms are functional, but less mature FreeBSD platforms. They are not supported by the security officer, release engineering, and Ports Management Team. Tier 2 platforms may be Tier 1 platform candidates that are still under active development. Architectures reaching end of life may also be moved from Tier 1 status to Tier 2 status as the availability of resources to continue to maintain the system in a Production Quality state diminishes. Well-supported niche architectures may also be Tier 2. The FreeBSD Project provides the following guarantees to consumers of Tier 2 platforms: * The ports infrastructure should include basic support for Tier 2 architectures sufficient to support building ports and packages. This includes support for basic packages such as ports-mgmt/pkg, but there is no guarantee that arbitrary ports will be buildable or functional. * New features which are not inherently platform-specific should be feasible on all Tier 2 architectures if not implemented. * Tier 2 platforms will be included in the source tree. * Tier 2 platforms should be self-hosting either via the in-tree toolchain or an external toolchain. If an external toolchain is required, official binary packages for an external toolchain will be provided. * Tier 2 platforms should provide functional kernels and userlands even if an official release distribution is not provided. To maintain maturity of Tier 2 platforms, the FreeBSD Project will maintain the following resources to support development: * Inclusion in the `make universe` and `make tinderbox` targets. Collectively, developers are required to provide the following to maintain the Tier 2 status of a platform: * Changes to the source tree should not knowingly break the build of a Tier 2 platform. * Tier 2 architectures must have an active ecosystem of users and developers. * While changes are permitted to break the userland ABI, the ABI should not be broken gratuitously. Significant userland ABI changes should be restricted to major versions. * New features that are not yet implemented on Tier 2 architectures should provide a means of disabling them on those architectures. ==== Tier 3: Experimental Architectures Tier 3 platforms have at least partial FreeBSD support. They are _not_ supported by the security officer, release engineering, and Ports Management Team. Tier 3 platforms are architectures in the early stages of development, for non-mainstream hardware platforms, or which are considered legacy systems unlikely to see broad future use. Initial support for Tier 3 platforms may exist in a separate repository rather than the main source repository. The FreeBSD Project provides no guarantees to consumers of Tier 3 platforms and is not committed to maintaining resources to support development. Tier 3 platforms may not always be buildable, nor are any kernel or userland ABIs considered stable. ==== Unsupported Architectures Other platforms are not supported in any form by the project. The project previously described these as Tier 4 systems. After a platform transitions to unsupported, all support for the platform is removed from the source, ports and documentation trees. Note that ports support should remain as long as the platform is supported in a branch supported by ports. === Policy on Changing the Tier of an Architecture Systems may only be moved from one tier to another by approval of the FreeBSD Core Team, which shall make that decision in collaboration with the Security Officer, Release Engineering, and ports management teams. For a platform to be promoted to a higher tier, any missing support guarantees must be satisfied before the promotion is completed. [[ports]] == Ports Specific FAQ [[ports-qa-adding]] === Adding a New Port [[ports-qa-add-new]] ==== How do I add a new port? Adding a port to the tree is relatively simple. Once the port is ready to be added, as explained later crossref:committers-guide[ports-qa-add-new-extra,here], you need to add the port's directory entry in the category's [.filename]#Makefile#. In this [.filename]#Makefile#, ports are listed in alphabetical order and added to the `SUBDIR` variable, like this: [.programlisting] .... SUBDIR += newport .... Once the port and its category's Makefile are ready, the new port can be committed: [source,shell] .... % git add category/Makefile category/newport % git commit % git push .... [TIP] ==== Don't forget to crossref:committers-guide[port-commit-message-formats,setup git hooks for the ports tree as explained here]; a specific hook has been developed to verify the category's [.filename]#Makefile#. ==== [[ports-qa-add-new-extra]] ==== Any other things I need to know when I add a new port? Check the port, preferably to make sure it compiles and packages correctly. The extref:{porters-handbook}testing[Porters Handbook's Testing Chapter] contains more detailed instructions. See the extref:{porters-handbook}testing[Portclippy / Portfmt, testing-portclippy] and the extref:{porters-handbook}testing[poudriere, testing-poudriere] sections. You do not necessarily have to eliminate all warnings but make sure you have fixed the simple ones. If the port came from a submitter who has not contributed to the Project before, add that person's name to the extref:{contributors}[Additional Contributors, contrib-additional] section of the FreeBSD Contributors List. Close the PR if the port came in as a PR. To close a PR, change the state to `Issue Resolved` and the resolution as `Fixed`. [NOTE] ==== If for some reason using extref:{porters-handbook}testing[poudriere, testing-poudriere] to test the new port is not possible, the bare minimum of testing includes this sequence: [source,shell] .... # make install # make package # make deinstall # pkg add package you built above # make deinstall # make reinstall # make package .... Note that poudriere is the reference for package building, it the port does not build in poudriere, it will be removed. ==== [[ports-qa-removing]] === Removing an Existing Port [[ports-qa-remove-one]] ==== How do I remove an existing port? First, please read the section about repository copies. Before you remove the port, you have to verify there are no other ports depending on it. * Make sure there is no dependency on the port in the ports collection: ** The port's PKGNAME appears in exactly one line in a recent INDEX file. ** No other ports contains any reference to the port's directory or PKGNAME in their Makefiles + [TIP] ==== When using Git, consider using man:git-grep[1], it is much faster than `grep -r`. ==== + * Then, remove the port: + [.procedure] ==== * Remove the port's files and directory with `git rm`. * Remove the `SUBDIR` listing of the port in the parent directory [.filename]#Makefile#. * Add an entry to [.filename]#ports/MOVED#. * Remove the port from [.filename]#ports/LEGAL# if it is there. ==== Alternatively, you can use the rmport script, from [.filename]#ports/Tools/scripts#. This script was written by {vd}. When sending questions about this script to the {freebsd-ports}, please also CC {crees}, the current maintainer. [[ports-qa-move-port]] === How do I move a port to a new location? [.procedure] ==== . Perform a thorough check of the ports collection for any dependencies on the old port location/name, and update them. Running `grep` on [.filename]#INDEX# is not enough because some ports have dependencies enabled by compile-time options. A full man:git-grep[1] of the ports collection is recommended. . Remove the `SUBDIR` entry from the old category Makefile and add a `SUBDIR` entry to the new category Makefile. . Add an entry to [.filename]#ports/MOVED#. . Search for entries in xml files inside [.filename]#ports/security/vuxml# and adjust them accordingly. In particular, check for previous packages with the new name which version could include the new port. . Move the port with `git mv`. . Commit the changes. ==== [[ports-qa-copy-port]] === How do I copy a port to a new location? [.procedure] ==== . Copy port with `cp -R old-cat/old-port new-cat/new-port`. . Add the new port to the [.filename]#new-cat/Makefile#. . Change stuff in [.filename]#new-cat/new-port#. . Commit the changes. ==== [[ports-qa-freeze]] === Ports Freeze [[ports-qa-freeze-what]] ==== What is a “ports freeze”? A “ports freeze” was a restricted state the ports tree was put in before a release. It was used to ensure a higher quality for the packages shipped with a release. It usually lasted a couple of weeks. During that time, build problems were fixed, and the release packages were built. This practice is no longer used, as the packages for the releases are built from the current stable, quarterly branch. For more information on how to merge commits to the quarterly branch, see crossref:committers-guide[ports-qa-misc-request-mfh, What is the procedure to request authorization for merging a commit to the quarterly branch?]. [[ports-qa-quarterly]] === Quarterly Branches [[ports-qa-misc-request-mfh]] ==== What is the procedure to request authorization for merging a commit to the quarterly branch? As of November 30, 2020, there is no need to seek explicit approval to commit to the quarterly branch. [[ports-qa-misc-commit-mfh]] ==== What is the procedure for merging commits to the quarterly branch? Merging commits to the quarterly branch (a process we call MFH for a historical reason) is very similar to MFC'ing a commit in the src repository, so basically: [source,shell] .... % git checkout 2021Q2 % git cherry-pick -x $HASH (verify everything is OK, for example by doing a build test) % git push .... where `$HASH` is the hash of the commit you want to copy over to the quarterly branch. The `-x` parameter ensures the hash `$HASH` of the `main` branch is included in the new commit message of the quarterly branch. [[ports-qa-new-category]] === Creating a New Category [[ports-qa-new-category-how]] ==== What is the procedure for creating a new category? Please see extref:{porters-handbook}makefiles[Proposing a New Category, proposing-categories] in the Porter's Handbook. Once that procedure has been followed and the PR has been assigned to the {portmgr}, it is their decision whether or not to approve it. If they do, it is their responsibility to: [.procedure] ==== . Perform any needed moves. (This only applies to physical categories.) . Update the `VALID_CATEGORIES` definition in [.filename]#ports/Mk/bsd.port.mk#. . Assign the PR back to you. ==== [[ports-qa-new-category-physical]] ==== What do I need to do to implement a new physical category? [.procedure] ==== . Upgrade each moved port's [.filename]#Makefile#. Do not connect the new category to the build yet. + To do this, you will need to: + [.procedure] ====== . Change the port's `CATEGORIES` (this was the point of the exercise, remember?) The new category is listed first. This will help to ensure that the PKGORIGIN is correct. . Run a `make describe`. Since the top-level `make index` that you will be running in a few steps is an iteration of `make describe` over the entire ports hierarchy, catching any errors here will save you having to re-run that step later on. . If you want to be really thorough, now might be a good time to run man:portlint[1]. ====== + . Check that the ``PKGORIGIN``s are correct. The ports system uses each port's `CATEGORIES` entry to create its `PKGORIGIN`, which is used to connect installed packages to the port directory they were built from. If this entry is wrong, common port tools like man:pkg-version[8] and man:portupgrade[1] fail. + To do this, use the [.filename]#chkorigin.sh# tool: `env PORTSDIR=/path/to/ports sh -e /path/to/ports/Tools/scripts/chkorigin.sh`. This will check every port in the ports tree, even those not connected to the build, so you can run it directly after the move operation. Hint: do not forget to look at the ``PKGORIGIN``s of any slave ports of the ports you just moved! . On your own local system, test the proposed changes: first, comment out the SUBDIR entries in the old ports' categories' [.filename]##Makefile##s; then enable building the new category in [.filename]#ports/Makefile#. Run make checksubdirs in the affected category directories to check the SUBDIR entries. Next, in the [.filename]#ports/# directory, run make index. This can take over 40 minutes on even modern systems; however, it is a necessary step to prevent problems for other people. . Once this is done, you can commit the updated [.filename]#ports/Makefile# to connect the new category to the build and also commit the [.filename]#Makefile# changes for the old category or categories. . Add appropriate entries to [.filename]#ports/MOVED#. . Update the documentation by modifying: ** the extref:{porters-handbook}makefiles[list of categories, porting-categories] in the Porter's Handbook + . Only once all the above have been done, and no one is any longer reporting problems with the new ports, should the old ports be deleted from their previous locations in the repository. ==== ==== What do I need to do to implement a new virtual category? This is much simpler than a physical category. Only a few modifications are needed: * the extref:{porters-handbook}makefiles[list of categories, porting-categories] in the Porter's Handbook [[ports-qa-misc-questions]] === Miscellaneous Questions [[ports-qa-misc-blanket-approval]] ==== Are there changes that can be committed without asking the maintainer for approval? Blanket approval for most ports applies to these types of fixes: * Most infrastructure changes to a port (that is, modernizing, but not changing the functionality). For example, the blanket covers converting to new `USES` macros, enabling verbose builds, and switching to new ports system syntaxes. * Trivial and _tested_ build and runtime fixes. * Documentations or metadata changes to ports, like [.filename]#pkg-descr# or `COMMENT`. [IMPORTANT] ==== Exceptions to this are anything maintained by the {portmgr}, or the {security-officer}. No unauthorized commits may ever be made to ports maintained by those groups. ==== [[ports-qa-misc-correctly-building]] ==== How do I know if my port is building correctly or not? The packages are built multiple times each week. If a port fails, the maintainer will receive an email from `pkg-fallout@FreeBSD.org`. Reports for all the package builds (official, experimental, and non-regression) are aggregated at link:https://pkg-status.FreeBSD.org[pkg-status.FreeBSD.org]. [[ports-qa-misc-INDEX]] ==== I added a new port. Do I need to add it to the [.filename]#INDEX#? No. The file can either be generated by running `make index`, or a pre-generated version can be downloaded with `make fetchindex`. [[ports-qa-misc-no-touch]] ==== Are there any other files I am not allowed to touch? Any file directly under [.filename]#ports/#, or any file under a subdirectory that starts with an uppercase letter ([.filename]#Mk/#, [.filename]#Tools/#, etc.). In particular, the {portmgr} is very protective of [.filename]#ports/Mk/bsd.port*.mk# so do not commit changes to those files unless you want to face their wrath. [[ports-qa-misc-updated-distfile]] ==== What is the proper procedure for updating the checksum for a port distfile when the file changes without a version change? When the checksum for a distribution file is updated due to the author updating the file without changing the port revision, the commit message includes a summary of the relevant diffs between the original and new distfile to ensure that the distfile has not been corrupted or maliciously altered. If the current version of the port has been in the ports tree for a while, a copy of the old distfile will usually be available on the ftp servers; otherwise the author or maintainer should be contacted to find out why the distfile has changed. [[ports-exp-run]] ==== How can an experimental test build of the ports tree (exp-run) be requested? An exp-run must be completed before patches with a significant ports impact are committed. The patch can be against the ports tree or the base system. Full package builds will be done with the patches provided by the submitter, and the submitter is required to fix detected problems _(fallout)_ before commit. [.procedure] ==== . Go to the link:https://bugs.freebsd.org/submit[Bugzilla new PR page]. . Select the product your patch is about. . Fill in the bug report as normal. Remember to attach the patch. . If at the top it says “Show Advanced Fields” click on it. It will now say “Hide Advanced Fields”. Many new fields will be available. If it already says “Hide Advanced Fields”, no need to do anything. . In the “Flags” section, set the “exp-run” one to `?`. As for all other fields, hovering the mouse over any field shows more details. . Submit. Wait for the build to run. . {portmgr} will reply with a possible fallout. . Depending on the fallout: ** If there is no fallout, the procedure stops here, and the change can be committed, pending any other approval required. ... If there is fallout, it _must_ be fixed, either by fixing the ports directly in the ports tree, or adding to the submitted patch. ... When this is done, go back to step 6 saying the fallout was fixed and wait for the exp-run to be run again. Repeat as long as there are broken ports. ==== [[non-committers]] == Issues Specific to Developers Who Are Not Committers A few people who have access to the FreeBSD machines do not have commit bits. Almost all of this document will apply to these developers as well (except things specific to commits and the mailing list memberships that go with them). In particular, we recommend that you read: * crossref:committers-guide[admin, Administrative Details] * crossref:committers-guide[conventions-everyone, For Everyone] + [NOTE] ==== Get your mentor to add you to the "Additional Contributors" ([.filename]#doc/shared/contrib-additional.adoc#), if you are not already listed there. ==== * crossref:committers-guide[developer.relations, Developer Relations] * crossref:committers-guide[ssh.guide, SSH Quick-Start Guide] * crossref:committers-guide[rules, The FreeBSD Committers' Big List of Rules] [[google-analytics]] == Information About Analytics The Project website uses https://plausible.io/[Plausible Analytics] to collect anonymized usage statistics regarding usage of the site since 2022. Previously, Google Analytics was enabled from December 12, 2012 to March 3, 2022. [[misc]] == Miscellaneous Questions === How do I access people.FreeBSD.org to put up personal or project information? `people.FreeBSD.org` is the same as `freefall.FreeBSD.org`. Just create a [.filename]#public_html# directory. Anything you place in that directory will automatically be visible under https://people.FreeBSD.org/[https://people.FreeBSD.org/]. === Where are the mailing list archives stored? The mailing lists are archived under [.filename]#/local/mail# on `freefall.FreeBSD.org`. === I would like to mentor a new committer. What process do I need to follow? See the https://www.freebsd.org/internal/new-account/[New Account Creation Procedure] document on the internal pages. [[benefits]] == Benefits and Perks for FreeBSD Committers [[benefits-recognition]] === Recognition Recognition as a competent software engineer is the longest lasting value. In addition, getting a chance to work with some of the best people that every engineer would dream of meeting is a great perk! [[benefits-gandi]] === `Gandi.net` https://gandi.net[Gandi] provides website hosting, cloud computing, domain registration, and X.509 certificate services. Gandi offers an E-rate discount to all FreeBSD developers. To streamline the process of getting the discount first set up a Gandi account, fill in the billing information and select the currency. Then send an email to mailto:non-profit@gandi.net[non-profit@gandi.net] using your `@freebsd.org` mail address, and indicate your Gandi handle. [[benefits-rsync]] === `rsync.net` https://rsync.net[rsync.net] provides cloud storage for offsite backup that is optimized for UNIX users. Their service runs entirely on FreeBSD and ZFS. rsync.net offers a free-forever 500 GB account to FreeBSD developers. Simply sign up at https://www.rsync.net/freebsd.html[https://www.rsync.net/freebsd.html] using your `@freebsd.org` address to receive this free account. [[benefits-watchgoose]] === `Watchgoose` https://watchgoose.com/[Watchgoose] provides hosted monitoring for cron jobs and backups, as well as other scheduled and recurring tasks that can send a start or completion signal. FreeBSD committers are eligible for a complimentary paid plan matched to their monitoring needs. To request access, create a Watchgoose.com account and email mailto:support@watchgoose.com[support@watchgoose.com] from an `@freebsd.org` address, including the email address used (from the FreeBSD.org domain) for the Watchgoose account. See the https://watchgoose.com/open-source/[Watchgoose Open Source support program] for more information. diff --git a/documentation/content/en/books/accessibility/partii.adoc b/documentation/content/en/books/accessibility/partii.adoc index 2001639e9c..4599518c3c 100644 --- a/documentation/content/en/books/accessibility/partii.adoc +++ b/documentation/content/en/books/accessibility/partii.adoc @@ -1,25 +1,33 @@ --- title: Part II. Vision prev: books/accessibility/help next: books/accessibility/virtual-terminal showBookMenu: true weight: 4 params: path: "/books/accessibility/partii/" --- +ifdef::env-beastie[] +ifdef::backend-html5[] +ifndef::chapters-path[] +include::shared/{{% lang %}}/urls.adoc[] +endif::[] +endif::[] +endif::[] + [[partii-vision]] = Vision Section for Assistive technologies for vision accessibility. The operating system provides two main interfaces for user interaction: Virtual Terminal and several Desktop Environments. Virtual Terminal, commonly referenced and documented as man:vt[4] is the system's built-in extref:{handbook}ports[virtual console]. It is installed by default, provides a command-line interface, and starts automatically at boot. Its features relevant to vision accessibility are detailed in the crossref:virtual-terminal[virtual-terminal,Virtual Terminal] chapter. Desktop environments provide graphical elements, such as windows, menus, buttons, and so on. They can be installed using extref:{handbook}ports[ports and packages]; refer to Chapters extref:{handbook}x11[X Window System], extref:{handbook}wayland[Wayland], and extref:{handbook}desktop[Desktop Environments] of the FreeBSD Handbook. This section explains how to install, configure, and use color schemes, themes, and visual accessibility features designed to support users with low vision or blindness in graphical environments. diff --git a/documentation/content/en/books/handbook/basics/_index.adoc b/documentation/content/en/books/handbook/basics/_index.adoc index 88c348a858..14bf5b3734 100644 --- a/documentation/content/en/books/handbook/basics/_index.adoc +++ b/documentation/content/en/books/handbook/basics/_index.adoc @@ -1,1962 +1,1962 @@ --- title: Chapter 3. FreeBSD Basics part: Part I. Getting Started prev: books/handbook/bsdinstall next: books/handbook/ports description: Basic commands and functionality of the FreeBSD operating system tags: ["basics", "virtual consoles", "users", "management", "permissions", "directory structure", "disk organization", "mounting", "processes", "daemons", "shell", "editor", "manual pages", "devices"] showBookMenu: true weight: 5 params: path: "/books/handbook/basics/" --- [[basics]] = FreeBSD Basics :doctype: book :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumoffset: 3 :partnums: :source-highlighter: rouge :experimental: :images-path: books/handbook/basics/ ifdef::env-beastie[] ifdef::backend-html5[] :imagesdir: ../../../../images/{images-path} endif::[] ifndef::book[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] toc::[] endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] toc::[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [[basics-synopsis]] == Synopsis This chapter covers the basic commands and functionality of the FreeBSD operating system. Much of this material is relevant for any UNIX(R)-like operating system. New FreeBSD users are encouraged to read through this chapter carefully. Read this chapter to learn: * How to use and configure virtual consoles. * How to create and manage users and groups on FreeBSD. * How UNIX(R) file permissions and FreeBSD file flags work. * The default FreeBSD file system layout. * The FreeBSD disk organization. * How to mount and unmount file systems. * What processes, daemons, and signals are. * What a shell is, and how to change the default login environment. * How to use basic text editors. * What devices and device nodes are. * How to read manual pages for more information. [[consoles]] == Virtual Consoles and Terminals Unless FreeBSD has been configured to automatically start a graphical environment during startup, the system will boot into a command line login prompt, as seen in this example: [.programlisting] .... FreeBSD/amd64 (pc3.example.org) (ttyv0) login: .... The first line contains some information about the system. The `amd64` indicates that FreeBSD is running on a 64-bit x86 system. The hostname is `pc3.example.org`, and `ttyv0` indicates that this is the "system console". The second line is the login prompt. Since FreeBSD is a multiuser system, it needs some way to distinguish between different users. This is accomplished by requiring every user to log into the system before gaining access to the programs on the system. Every user has a unique "username" and a personal "password". To log into the system console, type the username that was configured during system installation, as described in crossref:bsdinstall[bsdinstall-addusers,Add Users], and press kbd:[Enter]. Then enter the password associated with the username and press kbd:[Enter]. The password is _not echoed_ for security reasons. Once the correct password is input, the message of the day (MOTD) will be displayed followed by a command prompt. Depending upon the shell that was selected when the user was created, this prompt will be a `+#+`, `$`, or `%` character. The prompt indicates that the user is now logged into the FreeBSD system console and ready to try the available commands. [[consoles-virtual]] === Virtual Consoles While the system console can be used to interact with the system, a user working from the command line at the keyboard of a FreeBSD system will typically instead log into a virtual console. This is because system messages are configured by default to display on the system console. These messages will appear over the command or file that the user is working on, making it difficult to concentrate on the work at hand. By default, FreeBSD is configured to provide several virtual consoles for inputting commands. Each virtual console has its own login prompt and shell and it is easy to switch between virtual consoles. This essentially provides the command line equivalent of having several windows open at the same time in a graphical environment. The key combinations kbd:[Alt+F1] through kbd:[Alt+F8] have been reserved by FreeBSD for switching between virtual consoles. Use kbd:[Alt+F1] to switch to the system console (`ttyv0`), kbd:[Alt+F2] to access the first virtual console (`ttyv1`), kbd:[Alt+F3] to access the second virtual console (`ttyv2`), and so on. When using Xorg as a graphical console, the combination becomes kbd:[Ctrl+Alt+F1] to return to a text-based virtual console. When switching from one console to the next, FreeBSD manages the screen output. The result is an illusion of having multiple virtual screens and keyboards that can be used to type commands for FreeBSD to run. The programs that are launched in one virtual console do not stop running when the user switches to a different virtual console. Refer to man:kbdcontrol[1], man:vidcontrol[1], man:atkbd[4], man:syscons[4], and man:vt[4] for a more technical description of the FreeBSD console and its keyboard drivers. In FreeBSD, the number of available virtual consoles is configured in this section of `/etc/ttys`: [.programlisting] .... # name getty type status comments # ttyv0 "/usr/libexec/getty Pc" xterm on secure # Virtual terminals ttyv1 "/usr/libexec/getty Pc" xterm on secure ttyv2 "/usr/libexec/getty Pc" xterm on secure ttyv3 "/usr/libexec/getty Pc" xterm on secure ttyv4 "/usr/libexec/getty Pc" xterm on secure ttyv5 "/usr/libexec/getty Pc" xterm on secure ttyv6 "/usr/libexec/getty Pc" xterm on secure ttyv7 "/usr/libexec/getty Pc" xterm on secure ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure .... To disable a virtual console, put a comment symbol (`+#+`) at the beginning of the line representing that virtual console. For example, to reduce the number of available virtual consoles from eight to four, put a `+#+` in front of the last four lines representing virtual consoles `ttyv5` through `ttyv8`. _Do not_ comment out the line for the system console `ttyv0`. Note that the last virtual console (`ttyv8`) is used to access the graphical environment if Xorg has been installed and configured as described in crossref:x11[x11,The X Window System]. For a detailed description of every column in this file and the available options for the virtual consoles, refer to man:ttys[5]. [[consoles-singleuser]] === Single User Mode The FreeBSD boot menu provides an option labelled as "Boot Single User". If this option is selected, the system will boot into a special mode known as "single user mode". This mode is typically used to repair a system that will not boot or to reset the `root` password when it is not known. While in single user mode, networking and other virtual consoles are not available. However, full `root` access to the system is available, and by default, the `root` password is not needed. For these reasons, physical access to the keyboard is needed to boot into this mode and determining who has physical access to the keyboard is something to consider when securing a FreeBSD system. The settings which control single user mode are found in this section of `/etc/ttys`: [.programlisting] .... # name getty type status comments # # If console is marked "insecure", then init will ask for the root password # when going to single-user mode. console none unknown off secure .... By default, the status is set to `secure`. This assumes that who has physical access to the keyboard is either not important or it is controlled by a physical security policy. If this setting is changed to `insecure`, the assumption is that the environment itself is insecure because anyone can access the keyboard. When this line is changed to `insecure`, FreeBSD will prompt for the `root` password when a user selects to boot into single user mode. [NOTE] ==== _Be careful when changing this setting to `insecure`!_ If the `root` password is forgotten, booting into single user mode is still possible, but may be difficult for someone who is not familiar with the FreeBSD booting process. ==== [[consoles-vidcontrol]] === Changing Console Video Modes The FreeBSD console default video mode may be adjusted to 1024x768, 1280x1024, or any other size supported by the graphics chip and monitor. To use a different video mode load the `VESA` module: [source,shell] .... # kldload vesa .... To determine which video modes are supported by the hardware, use man:vidcontrol[1]. To get a list of supported video modes issue the following: [source,shell] .... # vidcontrol -i mode .... The output of this command lists the video modes that are supported by the hardware. To select a new video mode, specify the mode using man:vidcontrol[1] as the `root` user: [source,shell] .... # vidcontrol MODE_279 .... If the new video mode is acceptable, it can be permanently set on boot by adding it to `/etc/rc.conf`: [.programlisting] .... allscreens_flags="MODE_279" .... [[users-synopsis]] == Users and Basic Account Management FreeBSD allows multiple users to use the computer at the same time. While only one user can sit in front of the screen and use the keyboard at any one time, any number of users can log in to the system through the network. To use the system, each user should have their own user account. This chapter describes: * The different types of user accounts on a FreeBSD system. * How to add, remove, and modify user accounts. * How to set limits to control the resources that users and groups are allowed to access. * How to create groups and add users as members of a group. [[users-introduction]] === Account Types Since all access to the FreeBSD system is achieved using accounts and all processes are run by users, user and account management is important. There are three main types of accounts: system accounts, user accounts, and the superuser account. [[users-system]] ==== System Accounts System accounts are used to run services such as DNS, mail, and web servers. The reason for this is security; if all services ran as the superuser, they could act without restriction. Examples of system accounts are `daemon`, `operator`, `bind`, `news`, and `www`. `nobody` is the generic unprivileged system account. However, the more services that use `nobody`, the more files and processes that user will become associated with, and hence the more privileged that user becomes. [[users-user]] ==== User Accounts User accounts are assigned to real people and are used to log in and use the system. Every person accessing the system should have a unique user account. This allows the administrator to find out who is doing what and prevents users from clobbering the settings of other users. Each user can set up their own environment to accommodate their use of the system, by configuring their default shell, editor, key bindings, and language settings. Every user account on a FreeBSD system has certain information associated with it: User name:: The user name is typed at the `login:` prompt. Each user must have a unique user name. There are a number of rules for creating valid user names which are documented in man:passwd[5]. It is recommended to use user names that consist of eight or fewer, all lower case characters in order to maintain backwards compatibility with applications. Password:: Each account has an associated password. User ID (UID):: The User ID (UID) is a number used to uniquely identify the user to the FreeBSD system. Commands that allow a user name to be specified will first convert it to the UID. It is recommended to use a UID less than 65535, since higher values may cause compatibility issues with some software. Group ID (GID):: The Group ID (GID) is a number used to uniquely identify the primary group that the user belongs to. Groups are a mechanism for controlling access to resources based on a user's GID rather than their UID. This can significantly reduce the size of some configuration files and allows users to be members of more than one group. It is recommended to use a GID of 65535 or lower as higher GIDs may break some software. Login class:: Login classes are an extension to the group mechanism that provide additional flexibility when tailoring the system to different users. Login classes are discussed further in crossref:security[users-limiting,Configuring Login Classes]. Password change time:: By default, passwords do not expire. However, password expiration can be enabled on a per-user basis, forcing some or all users to change their passwords after a certain amount of time has elapsed. Account expiration time:: By default, FreeBSD does not expire accounts. When creating accounts that need a limited lifespan, such as student accounts in a school, specify the account expiry date using man:pw[8]. After the expiry time has elapsed, the account cannot be used to log in to the system, although the account's directories and files will remain. User's full name:: The user name uniquely identifies the account to FreeBSD, but does not necessarily reflect the user's real name. Similar to a comment, this information can contain spaces, uppercase characters, and be more than 8 characters long. Home directory:: The home directory is the full path to a directory on the system. This is the user's starting directory when the user logs in. A common convention is to put all user home directories under `/home/username` or `/usr/home/username`. Each user stores their personal files and subdirectories in their own home directory. User shell:: The shell provides the user's default environment for interacting with the system. There are many different kinds of shells and experienced users will have their own preferences, which can be reflected in their account settings. [[users-superuser]] ==== The Superuser Account The superuser account, usually called `root`, is used to manage the system with no limitations on privileges. For this reason, it should not be used for day-to-day tasks like sending and receiving mail, general exploration of the system, or programming. The superuser, unlike other user accounts, can operate without limits, and misuse of the superuser account may result in spectacular disasters. User accounts are unable to destroy the operating system by mistake, so it is recommended to login as a user account and to only become the superuser when a command requires extra privilege. Always double and triple-check any commands issued as the superuser, since an extra space or missing character can mean irreparable data loss. There are several ways to gain superuser privilege. While one can log in as `root`, this is highly discouraged. Instead, use man:su[1] to become the superuser. If `-` is specified when running this command, the user will also inherit the root user's environment. The user running this command must be in the `wheel` group or else the command will fail. The user must also know the password for the `root` user account. In this example, the user only becomes superuser in order to run `make install` as this step requires superuser privilege. Once the command completes, the user types `exit` to leave the superuser account and return to the privilege of their user account. .Install a Program As the Superuser [example] ==== [source,shell] .... % configure % make % su - Password: # make install # exit % .... ==== The built-in man:su[1] framework works well for single systems or small networks with just one system administrator. An alternative is to install the package:security/sudo[] package or port. This software provides activity logging and allows the administrator to configure which users can run which commands as the superuser. [[users-modifying]] === Managing Accounts FreeBSD provides a variety of different commands to manage user accounts. The most common commands are summarized in crossref:basics[users-modifying-utilities,Utilities for Managing User Accounts], followed by some examples of their usage. See the manual page for each utility for more details and usage examples. [[users-modifying-utilities]] .Utilities for Managing User Accounts [cols="25h,~"] |=== | Command | Summary |man:adduser[8] |The recommended command-line application for adding new users. |man:rmuser[8] |The recommended command-line application for removing users. |man:chpass[1] |A flexible tool for changing user database information. |man:passwd[1] |The command-line tool to change user passwords. |man:pw[8] |A powerful and flexible tool for modifying all aspects of user accounts. |man:bsdconfig[8] |A system configuration utility with account management support. |=== [[users-adduser]] ==== Adding a user The recommended program for adding new users is man:adduser[8]. When a new user is added, this program automatically updates `/etc/passwd` and `/etc/group`. It also creates a home directory for the new user, copies in the default configuration files from `/usr/share/skel`, and can optionally mail the new user a welcome message. This utility must be run as the superuser. The man:adduser[8] utility is interactive and walks through the steps for creating a new user account. As seen in crossref:basics[users-modifying-adduser, Adding a User on FreeBSD], either input the required information or press kbd:[Return] to accept the default value shown in square brackets. In this example, the user has been invited into the `wheel` group, allowing them to become the superuser with man:su[1]. When finished, the utility will prompt to either create another user or to exit. [[users-modifying-adduser]] .Adding a User on FreeBSD [example] ==== [source,shell] .... # adduser .... The output should be similar to the following: [.programlisting] .... Username: jru Full name: J. Random User Uid (Leave empty for default): Login group [jru]: Login group is jru. Invite jru into other groups? []: wheel Login class [default]: Shell (sh csh tcsh zsh nologin) [sh]: zsh Home directory [/home/jru]: Home directory permissions (Leave empty for default): Use password-based authentication? [yes]: Use an empty password? (yes/no) [no]: Use a random password? (yes/no) [no]: Enter password: Enter password again: Lock out the account after creation? [no]: Username : jru Password : **** Full Name : J. Random User Uid : 1001 Class : Groups : jru wheel Home : /home/jru Shell : /usr/local/bin/zsh Locked : no OK? (yes/no): yes adduser: INFO: Successfully added (jru) to the user database. Add another user? (yes/no): no Goodbye! .... ==== [NOTE] ==== Since the password is not echoed when typed, be careful to not mistype the password when creating the user account. ==== [[users-rmuser]] ==== Removing a user To completely remove a user from the system, run man:rmuser[8] as the superuser. This command performs the following steps: [.procedure] ==== . Removes the user's man:crontab[1] entry, if one exists. . Removes any man:at[1] jobs belonging to the user. . Sends a SIGKILL signal to all processes owned by the user. . Removes the user from the system's local password file. . Removes the user's home directory (if it is owned by the user), including handling of symbolic links in the path to the actual home directory. . Removes the incoming mail files belonging to the user from `/var/mail`. . Removes all files owned by the user from `/tmp`, `/var/tmp`, and `/var/tmp/vi.recover`. . Removes the username from all groups to which it belongs in `/etc/group`. (If a group becomes empty and the group name is the same as the username, the group is removed; this complements man:adduser[8]'s per-user unique groups.) . Removes all message queues, shared memory segments and semaphores owned by the user. ==== man:rmuser[8] cannot be used to remove superuser accounts since that is almost always an indication of massive destruction. By default, an interactive mode is used, as shown in the following example. .`rmuser` Interactive Account Removal [example] ==== [source,shell] .... # rmuser jru .... The output should be similar to the following: [.programlisting] .... Matching password entry: jru:*:1001:1001::0:0:J. Random User:/home/jru:/usr/local/bin/zsh Is this the entry you wish to remove? y Remove user's home directory (/home/jru)? y Removing user (jru): mailspool home passwd. .... ==== [[users-chpass]] ==== Change user information Any user can use man:chpass[1] to change their default shell and personal information associated with their user account. The superuser can use this utility to change additional account information for any user. When passed no options, aside from an optional username, man:chpass[1] displays an editor containing user information. When the user exits from the editor, the user database is updated with the new information. [NOTE] ==== This utility will prompt for the user's password when exiting the editor, unless the utility is run as the superuser. ==== In crossref:basics[users-modifying-chpass-su,Using `chpass` as Superuser], the superuser has typed `chpass jru` and is now viewing the fields that can be changed for this user. If `jru` runs this command instead, only the last six fields will be displayed and available for editing. This is shown in crossref:basics[users-modifying-chpass-ru,Using `chpass` as Regular User]. [[users-modifying-chpass-su]] .Using `chpass` as Superuser [example] ==== [source,shell] .... # chpass jru .... The output should be similar to the following: [.programlisting] .... # Changing user database information for jru. Login: jru Password: * Uid [#]: 1001 Gid [# or name]: 1001 Change [month day year]: Expire [month day year]: Class: Home directory: /home/jru Shell: /usr/local/bin/zsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information: .... ==== [[users-modifying-chpass-ru]] .Using `chpass` as Regular User [example] ==== [source,shell] .... #Changing user database information for jru. Shell: /usr/local/bin/zsh Full Name: J. Random User Office Location: Office Phone: Home Phone: Other information: .... ==== [NOTE] ==== The commands man:chfn[1] and man:chsh[1] are links to man:chpass[1], as are man:ypchpass[1], man:ypchfn[1], and man:ypchsh[1]. Since NIS support is automatic, specifying the `yp` before the command is not necessary. How to configure NIS is covered in crossref:network-servers[network-servers,Network Servers]. ==== [[users-passwd]] ==== Change user password Any user can easily change their password using man:passwd[1]. To prevent accidental or unauthorized changes, this command will prompt for the user's original password before a new password can be set: .Changing The Password [example] ==== [source,shell] .... % passwd .... The output should be similar to the following: [.programlisting] .... Changing local password for jru. Old password: New password: Retype new password: passwd: updating the database... passwd: done .... ==== The superuser can change any user's password by specifying the username when running man:passwd[1]. When this utility is run as the superuser, it will not prompt for the user's current password. This allows the password to be changed when a user cannot remember the original password. .Changing Another User's Password as the Superuser [example] ==== [source,shell] .... # passwd jru .... The output should be similar to the following: [.programlisting] .... Changing local password for jru. New password: Retype new password: passwd: updating the database... passwd: done .... ==== [NOTE] ==== As with man:chpass[1], man:yppasswd[1] is a link to man:passwd[1], so NIS works with either command. ==== [[users-pw]] ==== Create, remove, modify and display system users and groups The man:pw[8] utility can create, remove, modify, and display users and groups. It functions as a front end to the system user and group files. man:pw[8] has a very powerful set of command line options that make it suitable for use in shell scripts, but new users may find it more complicated than the other commands presented in this section. [[users-groups]] === Managing Groups A group is a list of users. A group is identified by its group name and GID. In FreeBSD, the kernel uses the UID of a process, and the list of groups it belongs to, to determine what the process is allowed to do. Most of the time, the GID of a user or process usually means the first group in the list. The group name to GID mapping is listed in `/etc/group`. This is a plain text file with four colon-delimited fields. The first field is the group name, the second is the encrypted password, the third the GID, and the fourth the comma-delimited list of members. For a complete description of the syntax, refer to man:group[5]. The superuser can modify `/etc/group` using a text editor, although editing the group file using man:vigr[8] is preferred because it can catch some common mistakes. Alternatively, man:pw[8] can be used to add and edit groups. For example, to add a group called `teamtwo` and then confirm that it exists: [WARNING] ==== Care must be taken when using the operator group, as unintended superuser-like access privileges may be granted, including but not limited to shutdown, reboot, and access to all items in `/dev` in the group. ==== .Adding a Group Using man:pw[8] [example] ==== [source,shell] .... # pw groupadd teamtwo # pw groupshow teamtwo .... The output should be similar to the following: [.programlisting] .... teamtwo:*:1100: .... ==== In this example, `1100` is the GID of `teamtwo`. Right now, `teamtwo` has no members. This command will add `jru` as a member of `teamtwo`. .Adding User Accounts to a New Group Using man:pw[8] [example] ==== [source,shell] .... # pw groupmod teamtwo -M jru # pw groupshow teamtwo .... The output should be similar to the following: [.programlisting] .... teamtwo:*:1100:jru .... ==== The argument to `-M` is a comma-delimited list of users to be added to a new (empty) group or to replace the members of an existing group. To the user, this group membership is different from (and in addition to) the user's primary group listed in the password file. This means that the user will not show up as a member when using `groupshow` with man:pw[8], but will show up when the information is queried via man:id[1] or a similar tool. When man:pw[8] is used to add a user to a group, it only manipulates `/etc/group` and does not attempt to read additional data from `/etc/passwd`. .Adding a New Member to a Group Using man:pw[8] [example] ==== [source,shell] .... # pw groupmod teamtwo -m db # pw groupshow teamtwo .... The output should be similar to the following: [.programlisting] .... teamtwo:*:1100:jru,db .... ==== In this example, the argument to `-m` is a comma-delimited list of users who are to be added to the group. Unlike the previous example, these users are appended to the group and do not replace existing users in the group. .Using man:id[1] to Determine Group Membership [example] ==== [source,shell] .... % id jru .... The output should be similar to the following: [.programlisting] .... uid=1001(jru) gid=1001(jru) groups=1001(jru), 1100(teamtwo) .... ==== In this example, `jru` is a member of the groups `jru` and `teamtwo`. For more information about this command and the format of `/etc/group`, refer to man:pw[8] and man:group[5]. [[permissions]] == Permissions In FreeBSD, every file and directory has an associated set of permissions and several utilities are available for viewing and modifying these permissions. Understanding how permissions work is necessary to make sure that users are able to access the files that they need and are unable to improperly access the files used by the operating system or owned by other users. This section discusses the traditional UNIX(R) permissions used in FreeBSD. For finer-grained file system access control, refer to crossref:security[fs-acl,Access Control Lists]. In UNIX(R), basic permissions are assigned using three types of access: read, write, and execute. These access types are used to determine file access to the file's owner, group, and others (everyone else). The read, write, and execute permissions can be represented as the letters `r`, `w`, and `x`. They can also be represented as binary numbers as each permission is either on or off (`0`). When represented as a number, the order is always read as `rwx`, where `r` has an on value of `4`, `w` has an on value of `2` and `x` has an on value of `1`. Table 4.1 summarizes the possible numeric and alphabetic possibilities. When reading the "Directory Listing" column, a `-` is used to represent a permission that is set to off. .UNIX(R) Permissions [cols="1,1,1", frame="none", options="header"] |=== | Value | Permission | Directory Listing |0 |No read, no write, no execute |`---` |1 |No read, no write, execute |`--x` |2 |No read, write, no execute |`-w-` |3 |No read, write, execute |`-wx` |4 |Read, no write, no execute |`r--` |5 |Read, no write, execute |`r-x` |6 |Read, write, no execute |`rw-` |7 |Read, write, execute |`rwx` |=== Use the `-l` argument with man:ls[1] to view a long directory listing that includes a column of information about a file's permissions for the owner, group, and everyone else. For example, `ls -l` in an arbitrary directory may show: [source,shell] .... % ls -l .... The output should be similar to the following: [.programlisting] .... total 530 -rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile -rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile -rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt .... Focusing on the line for `myfile`, the first `(leftmost)` character indicates whether this file is a regular file, a directory, a special character device, a socket, or any other special pseudo-file device. In this example, the `-` indicates a regular file. The next three characters, `rw-` in this example, give the permissions for the owner of the file. The next three characters, `r--`, give the permissions for the group that the file belongs to. The final three characters, `r--`, give the permissions for the rest of the world. A dash means that the permission is turned off. In this example, the permissions are set so the owner can read and write to the file, the group can read the file, and the rest of the world can only read the file. According to the table above, the permissions for this file would be `644`, where each digit represents the three parts of the file's permission. How does the system control permissions on devices? FreeBSD treats most hardware devices as a file that programs can open, read, and write data to. These special device files are stored in `/dev/`. Directories are also treated as files. They have read, write, and execute permissions. The executable bit for a directory has a slightly different meaning than that of files. When a directory is marked executable, it means it is possible to change into that directory using man:cd[1]. This also means that it is possible to access the files within that directory, subject to the permissions on the files themselves. In order to perform a directory listing, the read permission must be set on the directory. In order to delete a file that one knows the name of, it is necessary to have write _and_ execute permissions to the directory containing the file. There are more permission bits, but they are primarily used in special circumstances such as setuid binaries and sticky directories. For more information on file permissions and how to set them, refer to man:chmod[1]. === Symbolic Permissions Symbolic permissions use characters instead of octal values to assign permissions to files or directories. Symbolic permissions use the syntax of (who) (action) (permissions), where the following values are available: [.informaltable] [cols="1,1,1", frame="none", options="header"] |=== | Option | Letter | Represents |(who) |u |User |(who) |g |Group owner |(who) |o |Other |(who) |a |All ("world") |(action) |+ |Adding permissions |(action) |- |Removing permissions |(action) |= |Explicitly set permissions |(permissions) |r |Read |(permissions) |w |Write |(permissions) |x |Execute |(permissions) |t |Sticky bit |(permissions) |s |Set UID or GID |=== These values are used with man:chmod[1], but with letters instead of numbers. For example, the following command would block both members of the group associated with _FILE_ and all other users from accessing _FILE_: [source,shell] .... % chmod go= FILE .... A comma separated list can be provided when more than one set of changes to a file must be made. For example, the following command removes the group and "world" write permission on _FILE_, and adds the execute permissions for everyone: [source,shell] .... % chmod go-w,a+x FILE .... === FreeBSD File Flags In addition to file permissions, FreeBSD supports the use of "file flags". These flags add an additional level of security and control over files, but not directories. With file flags, even `root` can be prevented from removing or altering files. File flags are modified using man:chflags[1]. For example, to enable the system undeletable flag on the file `file1`, issue the following command: [source,shell] .... # chflags sunlink file1 .... To disable the system undeletable flag, put a "no" in front of the `sunlink`: [source,shell] .... # chflags nosunlink file1 .... To view the flags of a file, use `-lo` with man:ls[1]: [source,shell] .... # ls -lo file1 .... [.programlisting] .... -rw-r--r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1 .... Several file flags may only be added or removed by the `root` user. In other cases, the file owner may set its file flags. Refer to man:chflags[1] and man:chflags[2] for more information. === The setuid, setgid, and sticky Permissions Other than the permissions already discussed, there are three other specific settings that all administrators should know about. They are the `setuid`, `setgid`, and `sticky` permissions. These settings are important for some UNIX(R) operations as they provide functionality not normally granted to normal users. To understand them, the difference between the real user ID and effective user ID must be noted. The real user ID is the UID who owns or starts the process. The effective UID is the user ID the process runs as. As an example, man:passwd[1] runs with the real user ID when a user changes their password. However, in order to update the password database, the command runs as the effective ID of the `root` user. This allows users to change their passwords without seeing a `Permission Denied` error. The setuid permission may be added symbolically by adding the `s` permission for the user as in the following example: [source,shell] .... # chmod u+s suidexample.sh .... The setuid permission may also be set by prefixing a permission set with the number four (4) as shown in the following example: [source,shell] .... # chmod 4755 suidexample.sh .... The permissions on `suidexample.sh` now look like the following: [.programlisting] .... -rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh .... Note that a `s` is now part of the permission set designated for the file owner, replacing the executable bit. This allows utilities which need elevated permissions, such as man:passwd[1]. [NOTE] ==== The `nosuid` man:mount[8] option will cause such binaries to silently fail without alerting the user. That option is not completely reliable as a `nosuid` wrapper may be able to circumvent it. ==== To view this in real time, open two terminals. On one, type `passwd` as a normal user. While it waits for a new password, check the process table and look at the user information for man:passwd[1]: In terminal A: [source,shell] .... Changing local password for trhodes Old Password: .... In terminal B: [source,shell] .... # ps aux | grep passwd .... [source,shell] .... trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd .... Although man:passwd[1] is run as a normal user, it is using the effective UID of `root`. The `setgid` permission performs the same function as the `setuid` permission; except that it alters the group settings. When an application or utility executes with this setting, it will be granted the permissions based on the group that owns the file, not the user who started the process. To set the `setgid` permission on a file symbolically, add the `s` permission for the group with man:chmod[1]: [source,shell] .... # chmod g+s sgidexample.sh .... Alternatively, provide man:chmod[1] with a leading two (2): [source,shell] .... # chmod 2755 sgidexample.sh .... In the following listing, notice that the `s` is now in the field designated for the group permission settings: [source,shell] .... -rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh .... [NOTE] ==== In these examples, even though the shell script in question is an executable file, it will not run with a different EUID or effective user ID. This is because shell scripts may not access the man:setuid[2] system calls. ==== The `setuid` and `setgid` permission bits may lower system security, by allowing for elevated permissions. The third special permission, the `sticky bit`, can strengthen the security of a system. When the `sticky bit` is set on a directory, it allows file deletion only by the file owner. This is useful to prevent file deletion in public directories, such as `/tmp`, by users who do not own the file. To utilize this permission, add the `t` mode to the file: [source,shell] .... # chmod +t /tmp .... Alternatively, prefix the permission set with a one (1): [source,shell] .... # chmod 1777 /tmp .... The `sticky bit` permission will display as a `t` at the very end of the permission set: [source,shell] .... # ls -al / | grep tmp .... [source,shell] .... drwxrwxrwt 10 root wheel 512 Aug 31 01:49 tmp .... [[dirstructure]] == Directory Structure The FreeBSD directory hierarchy is fundamental to obtaining an overall understanding of the system. The most important directory is root or, "/". This directory is the first one mounted at boot time and it contains the base system necessary to prepare the operating system for multi-user operation. The root directory also contains mount points for other file systems that are mounted during the transition to multi-user operation. A mount point is a directory where additional file systems can be grafted onto a parent file system (usually the root file system). This is further described in crossref:basics[disk-organization, Disk Organization]. Standard mount points include `/usr/`, `/var/`, `/tmp/`, `/mnt/`, and `/media/`. These directories are usually referenced to entries in `/etc/fstab`. This file is a table of various file systems and mount points and is read by the system. Most of the file systems in `/etc/fstab` are mounted automatically at boot time from the script man:rc[8] unless their entry includes `noauto`. Details can be found in crossref:basics[disks-fstab, The fstab File]. A complete description of the file system hierarchy is available in man:hier[7]. The following table provides a brief overview of the most common directories. [cols="25h,~"] |=== | Directory | Description |`/` |Root directory of the file system. |`/bin/` |User utilities fundamental to both single-user and multi-user environments. |`/boot/` |Programs and configuration files used during operating system bootstrap. |`/boot/defaults/` |Default boot configuration files. Refer to man:loader.conf[5] for details. |`/dev/` |Device special files managed by man:devfs[5] |`/etc/` |System configuration files and scripts. |`/etc/defaults/` |Default system configuration files. Refer to man:rc[8] for details. |`/etc/periodic/` |Scripts that run daily, weekly, and monthly, via man:cron[8]. Refer to man:periodic[8] for details. |`/lib/` |Critical system libraries needed for binaries in `/bin` and `/sbin` |`/libexec/` |Critical system files |`/media/` |Contains subdirectories to be used as mount points for removable media such as CDs, USB drives, and floppy disks |`/mnt/` |Empty directory commonly used by system administrators as a temporary mount point. |`/net/` |Automounted NFS shares; see man:auto_master[5] |`/proc/` |Process file system. Refer to man:procfs[5] for details. |`/rescue/` |Statically linked programs for emergency recovery as described in man:rescue[8]. |`/root/` |Home directory for the `root` account. |`/sbin/` |System programs and administration utilities fundamental to both single-user and multi-user environments. |`/tmp/` |Temporary files which are usually _not_ preserved across a system reboot. A memory-based file system is often mounted at `/tmp`. This can be automated using the tmpmfs-related variables of man:rc.conf[5] or with an entry in `/etc/fstab`; refer to man:mdmfs[8] for details. |`/usr/` |The majority of user utilities and applications. |`/usr/bin/` |Common utilities, programming tools, and applications. |`/usr/include/` |Standard C include files. |`/usr/lib/` |Archive libraries. |`/usr/libdata/` |Miscellaneous utility data files. |`/usr/libexec/` |System daemons and system utilities executed by other programs. |`/usr/local/` |Local executables and libraries. Also used as the default destination for the FreeBSD ports framework. Within `/usr/local`, the general layout sketched out by man:hier[7] for `/usr` should be used. Exceptions are the man directory, which is directly under `/usr/local` rather than under `/usr/local/share`, and the ports documentation is in `share/doc/port`. |`/usr/ports/` |The FreeBSD Ports Collection (optional). |`/usr/sbin/` |System daemons and system utilities executed by users. |`/usr/share/` |Architecture-independent files. |`/usr/src/` |BSD and/or local source files. |`/var/` |Multi-purpose log, temporary, transient, and spool files. |`/var/log/` |Miscellaneous system log files. |`/var/tmp/` |Temporary files which are usually preserved across a system reboot. |=== [[disk-organization]] == Disk Organization The smallest unit of organization that FreeBSD uses to find files is the filename. Filenames are case-sensitive, which means that `readme.txt` and `README.TXT` are two separate files. FreeBSD does not use the extension of a file to determine whether the file is a program, document, or some other form of data. Files are stored in directories. A directory may contain no files, or it may contain many hundreds of files. A directory can also contain other directories, allowing a hierarchy of directories within one another in order to organize data. Files and directories are referenced by giving the file or directory name, followed by a forward slash, `/`, followed by any other directory names that are necessary. For example, if the directory `foo` contains a directory `bar` which contains the file `readme.txt`, the full name, or _path_, to the file is `foo/bar/readme.txt`. Note that this is different from Windows(R) which uses `\` to separate file and directory names. FreeBSD does not use drive letters, or other drive names in the path. For example, one would not type `c:\foo\bar\readme.txt` on FreeBSD. [[disks-file-systems]] === File systems Directories and files are stored in a file system. Each file system contains exactly one directory at the very top level, called the _root directory_ for that file system. This root directory can contain other directories. One file system is designated the _root file system_ or `/`. Every other file system is _mounted_ under the root file system. No matter how many disks are on the FreeBSD system, every directory appears to be part of the same disk. Consider three file systems, called `A`, `B`, and `C`. Each file system has one root directory, which contains two other directories, called `A1`, `A2` (and likewise `B1`, `B2` and `C1`, `C2`). Call `A` the root file system. If man:ls[1] is used to view the contents of this directory, it will show two subdirectories, `A1` and `A2`. The directory tree looks like this: -image::example-dir1.png[Directory tree with the root directory and two subdirectories, A1 and A2] +image::example-dir1.png["Directory tree with the root directory and two subdirectories, A1 and A2"] A file system must be mounted on to a directory in another file system. When mounting file system `B` on to the directory `A1`, the root directory of `B` replaces `A1`, and the directories in `B` appear accordingly: -image::example-dir2.png[Directory tree with the root directory and two subdirectories, A1 and A2. And more subdirectories, B1 and B2 hanging from A1] +image::example-dir2.png["Directory tree with the root directory and two subdirectories, A1 and A2. And more subdirectories, B1 and B2 hanging from A1"] Any files that are in the `B1` or `B2` directories can be reached with the path `/A1/B1` or `/A1/B2` as necessary. Any files that were in `/A1` have been temporarily hidden. They will reappear if `B` is _unmounted_ from `A`. If `B` had been mounted on `A2` then the diagram would look like this: -image::example-dir3.png[Directory tree with the root directory and two subdirectories, A1 and A2. And more subdirectories, B1 and B2 hanging from A2] +image::example-dir3.png["Directory tree with the root directory and two subdirectories, A1 and A2. And more subdirectories, B1 and B2 hanging from A2"] and the paths would be `/A2/B1` and `/A2/B2` respectively. File systems can be mounted on top of one another. Continuing the last example, the `C` file system could be mounted on top of the `B1` directory in the `B` file system, leading to this arrangement: image::example-dir4.png[A complex directory tree. With different subdirectories hanging from root.] Or `C` could be mounted directly on to the `A` file system, under the `A1` directory: -image::example-dir5.png[A complex directory tree. With different subdirectories hanging from root.] +image::example-dir5.png["A complex directory tree. With different subdirectories hanging from root."] It is entirely possible to have one large root file system, and not need to create any others. There are some drawbacks to this approach, and one advantage. .Benefits of Multiple File Systems * Different file systems can have different _mount options_. For example, the root file system can be mounted read-only, making it impossible for users to inadvertently delete or edit a critical file. Separating user-writable file systems, such as `/home`, from other file systems allows them to be mounted _nosuid_. This option prevents the _suid_/_guid_ bits on executables stored on the file system from taking effect, possibly improving security. * FreeBSD automatically optimizes the layout of files on a file system, depending on how the file system is being used. So a file system that contains many small files that are written frequently will have a different optimization to one that contains fewer, larger files. By having one big file system this optimization breaks down. * FreeBSD's file systems are robust if power is lost. However, a power loss at a critical point could still damage the structure of the file system. By splitting data over multiple file systems it is more likely that the system will still come up, making it easier to restore from backup as necessary. .Benefit of a Single File System * File systems are a fixed size. When creating a file system during the FreeBSD installation and giving it a specific size, it may be that one wants to make the partition bigger. This is not easily accomplished without backing up, recreating the file system with the new size, and then restoring the backed up data. + [IMPORTANT] ==== FreeBSD features the man:growfs[8] command, which makes it possible to increase the size of file system on the fly, removing this limitation. A file system can only be expanded into free space in the partition in which it resides. If there is space after the partition, the partition can be expanded with man:gpart[8]. If the partition is the last one on a virtual disk, and the disk is expanded, the partition can then be expanded. ==== [[disks-partitions]] === Disk partitions File systems are contained in _partitions_. Disks are divided into partitions using one of several partitioning schemes; see crossref:bsdinstall[bsdinstall-part-manual, Manual Partitioning]. The newer scheme is GPT; older BIOS-based computers use MBR. GPT supports division of a disk into partitions with a size, offset, and type. It supports a large number of partitions and partition types, and is recommended whenever its use is possible. GPT partitions use the disk name with a suffix, where the suffix is `p1` for the first partition, `p2` for the second, and so on. MBR, however, supports only a small number of partitions. The MBR partitions are known in FreeBSD as `slices`. Slices may be used for different operating systems. FreeBSD slices are subdivided into partitions using BSD labels (see man:bsdlabel[8]). Slice numbers follow the device name, prefixed with an `s`, starting at 1. So "da0__s1__" is the first slice on the first SCSI drive. There can only be four physical slices on a disk, but there can be logical slices inside physical slices of the appropriate type. These extended slices are numbered starting at 5, so "ada0__s5__" is the first extended slice on the first SATA disk. These devices are used by file systems that expect to occupy a slice. Each GPT or BSD partition can contain only one file system, which means that file systems are often described by either their typical mount point in the file system hierarchy, or the name of the partition they are contained in. FreeBSD also uses disk space for _swap space_ to provide _virtual memory_. This allows the computer to behave as though it has much more memory than it actually does. When FreeBSD runs out of memory, it moves some of the data that is not currently being used to the swap space, and moves it back in (moving something else out) when it needs it. This is called _paging_. Some BSD partitions have certain conventions associated with them. [cols="25h,~"] |=== | Partition | Convention |`a` |Normally contains the root file system. |`b` |Normally contains swap space. |`c` |Normally the same size as the enclosing slice. This allows utilities that need to work on the entire slice, such as a bad block scanner, to work on the `c` partition. A file system would not normally be created on this partition. |`d` |Partition `d` used to have a special meaning associated with it, although that is now gone and `d` may work as any normal partition. |=== Slices and "dangerously dedicated" physical drives contain BSD partitions, which are represented as letters from `a` to `h`. This letter is appended to the device name, so "da0__a__" is the `a` partition on the first `da` drive, which is "dangerously dedicated". "ada1s3__e__" is the fifth partition in the third slice of the second SATA disk drive. Finally, each disk on the system is identified. A disk name starts with a code that indicates the type of disk, and then a number, indicating which disk it is. Unlike partitions and slices, disk numbering starts at 0. Common codes are listed in crossref:basics[disks-naming,Disk Device Names]. When referring to a partition in a slice, include the disk name, `s`, the slice number, and then the partition letter. Examples are shown in crossref:basics[basics-disk-slice-part,"Sample Disk, Slice, and Partition Names"]. GPT partitions include the disk name, `p`, and then the partition number. crossref:basics[basics-concept-disk-model,Conceptual Model of a Disk] shows a conceptual model of a disk layout using MBR slices. When installing FreeBSD, configure the disk slices if using MBR, and create partitions within the slice to be used for FreeBSD. If using GPT, configure partitions for each file system. In either case, create a file system or swap space in each partition, and decide where each file system will be mounted. See man:gpart[8] for information on manipulating partitions. [[disks-naming]] .Disk Device Names [cols="1,1", frame="none", options="header"] |=== | Drive Type | Drive Device Name |SATA and IDE hard drives |`ada` |SCSI hard drives and USB storage devices |`da` |NVMe storage |`nvd` or `nda` |SATA and IDE CD-ROM drives |`cd` |SCSI CD-ROM drives |`cd` |Floppy drives |`fd` |SCSI tape drives |`sa` |RAID drives |Examples include `aacd` for Adaptec(R) AdvancedRAID, `mlxd` and `mlyd` for Mylex(R), `amrd` for AMI MegaRAID(R), `idad` for Compaq Smart RAID, `twed` for 3ware(R) RAID. |=== [example] ==== [[basics-disk-slice-part]] .Sample Disk, Slice, and Partition Names [.informaltable] [cols="1,1", frame="none", options="header"] |=== | Name | Meaning |`ada0s1a` |The first partition (`a`) on the first slice (`s1`) on the first SATA disk (`ada0`). |`da1s2e` |The fifth partition (`e`) on the second slice (`s2`) on the second SCSI disk (`da1`). |=== ==== [[basics-concept-disk-model]] .Conceptual Model of a Disk [example] ==== This diagram shows FreeBSD's view of the first SATA disk attached to the system. Assume that the disk is 250 GB in size, and contains an 80 GB slice and a 170 GB slice (MS-DOS(R) partitions). The first slice contains a Windows(R) NTFS file system, `C:`, and the second slice contains a FreeBSD installation. This example FreeBSD installation has four data partitions and a swap partition. The four partitions each hold a file system. Partition `a` is used for the root file system, `d` for `/var/`, `e` for `/tmp/`, and `f` for `/usr/`. Partition letter `c` refers to the entire slice, and so is not used for ordinary partitions. image::disk-layout.png[Layout of a shared drive between Windows and FreeBSD] ==== [[mount-unmount]] == Mounting and Unmounting File Systems The file system is best visualized as a tree, rooted, as it were, at `/`. `/dev`, `/usr`, and the other directories in the root directory are branches, which may have their own branches, such as `/usr/local`, and so on. There are various reasons to house some of these directories on separate file systems. `/var` contains the directories `log/`, `spool/`, and various types of temporary files, and as such, may get filled up. Filling up the root file system is not a good idea, so splitting `/var` from `/` is often favorable. Another common reason to contain certain directory trees on other file systems is if they are to be housed on separate physical disks, or are separate virtual disks, such as Network File System mounts, described in crossref:network-servers[network-nfs,“Network File System (NFS)”], or CDROM drives. [[disks-fstab]] === The fstab File During the boot process (crossref:boot[boot,The FreeBSD Booting Process]), file systems listed in `/etc/fstab` are automatically mounted except for the entries containing `noauto`. This file contains entries in the following format: [.programlisting] .... device /mount-point fstype options dumpfreq passno .... `device`:: An existing device name as explained in crossref:basics[disks-naming,Disk Device Names]. `mount-point`:: An existing directory on which to mount the file system. `fstype`:: The file system type to pass to man:mount[8]. The default FreeBSD file system is `ufs`. `options`:: Either `rw` for read-write file systems, or `ro` for read-only file systems, followed by any other options that may be needed. A common option is `noauto` for file systems not normally mounted during the boot sequence. Other options are listed in man:mount[8]. `dumpfreq`:: Used by man:dump[8] to determine which file systems require dumping. If the field is missing, a value of zero is assumed. `passno`:: Determines the order in which UFS file systems should be checked by man:fsck[8] after a reboot. File systems that should be skipped should have their `passno` set to zero. The root file system needs to be checked before everything else and should have its `passno` set to one. The other file systems should be set to values greater than one. If more than one file system has the same `passno`, man:fsck[8] will attempt to check file systems in parallel if possible. Refer to man:fstab[5] for more information on the format of `/etc/fstab` and its options. [[disks-mount]] === Using man:mount[8] File systems are mounted using man:mount[8]. The most basic syntax is as follows: [example] ==== [source,shell] .... # mount device mountpoint .... ==== A file system listed in `/etc/fstab` can also be mounted by providing just the mountpoint. This command provides many options which are described in man:mount[8]. The most commonly used options include: .Mount Options `-a`:: Mount all the file systems listed in `/etc/fstab`, except those marked as "noauto", excluded by the `-t` flag, or those that are already mounted. `-d`:: Do everything except for the actual mount system call. This option is useful in conjunction with the `-v` flag to determine what man:mount[8] is actually trying to do. `-f`:: Force the mount of an unclean file system (dangerous), or the revocation of write access when downgrading a file system's mount status from read-write to read-only. `-r`:: Mount the file system read-only. This is identical to using `-o ro`. ``-t _fstype_``:: Mount the specified file system type or mount only file systems of the given type, if `-a` is included. "ufs" is the default file system type. `-u`:: Update mount options on the file system. `-v`:: Be verbose. `-w`:: Mount the file system read-write. The following options can be passed to `-o` as a comma-separated list: nosuid:: Do not interpret setuid or setgid flags on the file system. This is also a useful security option. [[disks-umount]] === Using man:umount[8] To unmount a file system use man:umount[8]. This command takes one parameter which can be a mountpoint, device name, `-a` or `-A`. All forms take `-f` to force unmounting, and `-v` for verbosity. Be warned that `-f` is not generally a good idea as it might crash the computer or damage data on the file system. To unmount all mounted file systems, or just the file system types listed after `-t`, use `-a` or `-A`. Note that `-A` does not attempt to unmount the root file system. [[basics-processes]] == Processes and Daemons FreeBSD is a multi-tasking operating system. Each program running at any one time is called a _process_. Every running command starts at least one new process and there are a number of system processes that are run by FreeBSD. Each process is uniquely identified by a number called a _process ID_ (PID). Similar to files, each process has one owner and group, and the owner and group permissions are used to determine which files and devices the process can open. Most processes also have a parent process that started them. For example, the shell is a process, and any command started in the shell is a process which has the shell as its parent process. The exception is a special process called man:init[8] which is always the first process to start at boot time and which always has a PID of `1`. Some programs are not designed to be run with continuous user input and disconnect from the terminal at the first opportunity. For example, a web server responds to web requests, rather than user input. Mail servers are another example of this type of application. These types of programs are known as _daemons_. The term daemon comes from Greek mythology and represents an entity that is neither good nor evil, and which invisibly performs useful tasks. This is why the BSD mascot is the cheerful-looking daemon with sneakers and a pitchfork. There is a convention to name programs that normally run as daemons with a trailing "d". For example, BIND is the Berkeley Internet Name Domain, but the actual program that executes is `named`. The Apache web server program is `httpd` and the line printer spooling daemon is `lpd`. This is only a naming convention. For example, the main mail daemon for the Sendmail application is `sendmail`, and not `maild`. === Viewing Processes To see the processes running on the system, use man:ps[1] or man:top[1]. To display a static list of the currently running processes, their PIDs, how much memory they are using, and the command they were started with, use man:ps[1]. To display all the running processes and update the display every few seconds in order to interactively see what the computer is doing, use man:top[1]. By default, man:ps[1] only shows the commands that are running and owned by the user. For example: [source,shell] .... % ps .... The output should be similar to the following: [.programlisting] .... PID TT STAT TIME COMMAND 8203 0 Ss 0:00.59 /bin/csh 8895 0 R+ 0:00.00 ps .... The output from man:ps[1] is organized into a number of columns. The `PID` column displays the process ID. PIDs are assigned starting at 1, go up to 99999, then wrap around back to the beginning. However, a PID is not reassigned if it is already in use. The `TT` column shows the tty the program is running on and `STAT` shows the program's state. `TIME` is the amount of time the program has been running on the CPU. This is usually not the elapsed time since the program was started, as most programs spend a lot of time waiting for things to happen before they need to spend time on the CPU. Finally, `COMMAND` is the command that was used to start the program. A number of different options are available to change the information that is displayed. One of the most useful sets is `auxww`, where `a` displays information about all the running processes of all users, `u` displays the username and memory usage of the process' owner, `x` displays information about daemon processes, and `ww` causes man:ps[1] to display the full command line for each process, rather than truncating it once it gets too long to fit on the screen. The output from man:top[1] is similar: [source,shell] .... % top .... The output should be similar to the following: [.programlisting] .... last pid: 9609; load averages: 0.56, 0.45, 0.36 up 0+00:20:03 10:21:46 107 processes: 2 running, 104 sleeping, 1 zombie CPU: 6.2% user, 0.1% nice, 8.2% system, 0.4% interrupt, 85.1% idle Mem: 541M Active, 450M Inact, 1333M Wired, 4064K Cache, 1498M Free ARC: 992M Total, 377M MFU, 589M MRU, 250K Anon, 5280K Header, 21M Other Swap: 2048M Total, 2048M Free PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND 557 root 1 -21 r31 136M 42296K select 0 2:20 9.96% Xorg 8198 dru 2 52 0 449M 82736K select 3 0:08 5.96% kdeinit4 8311 dru 27 30 0 1150M 187M uwait 1 1:37 0.98% firefox 431 root 1 20 0 14268K 1728K select 0 0:06 0.98% moused 9551 dru 1 21 0 16600K 2660K CPU3 3 0:01 0.98% top 2357 dru 4 37 0 718M 141M select 0 0:21 0.00% kdeinit4 8705 dru 4 35 0 480M 98M select 2 0:20 0.00% kdeinit4 8076 dru 6 20 0 552M 113M uwait 0 0:12 0.00% soffice.bin 2623 root 1 30 10 12088K 1636K select 3 0:09 0.00% powerd 2338 dru 1 20 0 440M 84532K select 1 0:06 0.00% kwin 1427 dru 5 22 0 605M 86412K select 1 0:05 0.00% kdeinit4 .... The output is split into two sections. The header (the first five or six lines) shows the PID of the last process to run, the system load averages (which are a measure of how busy the system is), the system uptime (time since the last reboot) and the current time. The other figures in the header relate to how many processes are running, how much memory and swap space has been used, and how much time the system is spending in different CPU states. If the ZFS file system module has been loaded, an `ARC` line indicates how much data was read from the memory cache instead of from disk. Below the header is a series of columns containing similar information to the output from man:ps[1], such as the PID, username, amount of CPU time, and the command that started the process. By default, man:top[1] also displays the amount of memory space taken by the process. This is split into two columns: one for total size and one for resident size. Total size is how much memory the application has needed and the resident size is how much it is actually using now. man:top[1] automatically updates the display every two seconds. A different interval can be specified with `-s`. [[basics-daemons]] === Killing Processes One way to communicate with any running process or daemon is to send a _signal_ using man:kill[1]. There are a number of different signals; some have a specific meaning while others are described in the application's documentation. A user can only send a signal to a process they own and sending a signal to someone else's process will result in a permission denied error. The exception is the `root` user, who can send signals to anyone's processes. The operating system can also send a signal to a process. If an application is badly written and tries to access memory that it is not supposed to, FreeBSD will send the process the "Segmentation Violation" signal (`SIGSEGV`). If an application has been written to use the man:alarm[3] system call to be alerted after a period of time has elapsed, it will be sent the "Alarm" signal (`SIGALRM`). Two signals can be used to stop a process: `SIGTERM` and `SIGKILL`. `SIGTERM` is the polite way to kill a process as the process can read the signal, close any log files it may have open, and attempt to finish what it is doing before shutting down. In some cases, a process may ignore `SIGTERM` if it is in the middle of some task that cannot be interrupted. `SIGKILL` cannot be ignored by a process. Sending a `SIGKILL` to a process will usually stop that process there and then. footnote:[There are a few tasks that cannot be interrupted. For example, if the process is trying to read from a file that is on another computer on the network, and the other computer is unavailable, the process is said to be uninterruptible. Eventually the process will time out, typically after two minutes. As soon as this time out occurs the process will be killed.]. Other commonly used signals are `SIGHUP`, `SIGUSR1`, and `SIGUSR2`. Since these are general purpose signals, different applications will respond differently. For example, after changing a web server's configuration file, the web server needs to be told to re-read its configuration. Restarting `httpd` would result in a brief outage period on the web server. Instead, send the daemon the `SIGHUP` signal. Be aware that different daemons will have different behavior, so refer to the documentation for the daemon to determine if `SIGHUP` will achieve the desired results. [IMPORTANT] ==== Killing a random process on the system is a bad idea. In particular, man:init[8], PID 1, is special. Running `/bin/kill -s KILL 1` is a quick, and unrecommended, way to shutdown the system. _Always_ double check the arguments to man:kill[1] _before_ pressing kbd:[Return]. ==== [[shells]] == Shells A _shell_ provides a command line interface for interacting with the operating system. A shell receives commands from the input channel and executes them. Many shells provide built in functions to help with everyday tasks such as file management, file globbing, command line editing, command macros, and environment variables. FreeBSD comes with several shells, including an extended POSIX(R) shell (man:sh[1]) and the extended C shell (man:tcsh[1]). Other shells are available from the FreeBSD Ports Collection, such as `zsh` and `bash`. The shell that is used is really a matter of taste. A C programmer might feel more comfortable with a C-like shell such as man:tcsh[1]. A Linux(R) user might prefer `bash`. Each shell has unique properties that may or may not work with a user's preferred working environment, which is why there is a choice of which shell to use. One common shell feature is filename completion. After a user types the first few letters of a command or filename and presses kbd:[Tab], the shell completes the rest of the command or filename. Consider two files called `foobar` and `football`. To delete `foobar`, the user might type `rm foo` and press kbd:[Tab] to complete the filename. But the shell only shows `rm foo`. It was unable to complete the filename because both `foobar` and `football` start with `foo`. Some shells sound a beep or show all the choices if more than one name matches. The user must then type more characters to identify the desired filename. Typing a `t` and pressing kbd:[Tab] again is enough to let the shell determine which filename is desired and fill in the rest. Another feature of the shell is the use of environment variables. Environment variables are a variable/key pair stored in the shell's environment. This environment can be read by any program invoked by the shell, and thus contains a lot of program configuration. crossref:basics[shell-env-vars,Common Environment Variables] provides a list of common environment variables and their meanings. Note that the names of environment variables are always in uppercase. [[shell-env-vars]] .Common Environment Variables [cols="25h,~"] |=== | Variable | Description |`USER` |Current logged in user's name. |`PATH` |Colon-separated list of directories to search for binaries. |`DISPLAY` |Network name of the Xorg display to connect to, if available. |`SHELL` |The current shell. |`TERM` |The name of the user's type of terminal. Used to determine the capabilities of the terminal. |`TERMCAP` |Database entry of the terminal escape codes to perform various terminal functions. |`OSTYPE` |Type of operating system. |`MACHTYPE` |The system's CPU architecture. |`EDITOR` |The user's preferred text editor. |`PAGER` |The user's preferred utility for viewing text one page at a time. |`MANPATH` |Colon-separated list of directories to search for manual pages. |=== How to set an environment variable differs between shells. In man:tcsh[1] and man:csh[1], use `setenv` to set environment variables. In man:sh[1] and `bash`, use `export` to set the current environment variables. This example sets the default `EDITOR` to `/usr/local/bin/emacs` for the man:tcsh[1] shell: [source,shell] .... % setenv EDITOR /usr/local/bin/emacs .... The equivalent command for `bash` would be: [source,shell] .... % export EDITOR="/usr/local/bin/emacs" .... To expand an environment variable in order to see its current setting, type a `$` character in front of its name on the command line. For example, `echo $TERM` displays the current `$TERM` setting. Shells treat special characters, known as meta-characters, as special representations of data. The most common meta-character is `\*`, which represents any number of characters in a filename. Meta-characters can be used to perform filename globbing. For example, `echo *` is equivalent to `ls` because the shell takes all the files that match `*` and `echo` lists them on the command line. To prevent the shell from interpreting a special character, escape it from the shell by starting it with a backslash (`\`). For example, `echo $TERM` prints the terminal setting whereas `echo \$TERM` literally prints the string `$TERM`. [[changing-shells]] === Changing the Shell The easiest way to permanently change the default shell is to use `chsh`. Running this command will open the editor that is configured in the `EDITOR` environment variable, which by default is set to man:vi[1]. Change the `Shell:` line to the full path of the new shell. Alternately, use `chsh -s` which will set the specified shell without opening an editor. For example, to change the shell to `bash`: [source,shell] .... % chsh -s /usr/local/bin/bash .... Enter the password at the prompt and press kbd:[Return] to change the shell. Log off and log in again to start using the new shell. [NOTE] ==== The new shell _must_ be present in `/etc/shells`. If the shell was installed from the FreeBSD Ports Collection as described in crossref:ports[ports,Installing Applications: Packages and Ports], it should be automatically added to this file. If it is missing, add it using this command, replacing the path with the path of the shell: [source,shell] .... # echo /usr/local/bin/bash >> /etc/shells .... Then, rerun man:chsh[1]. ==== === Advanced Shell Techniques The UNIX(R) shell is not just a command interpreter, it acts as a powerful tool which allows users to execute commands, redirect their output, redirect their input and chain commands together to improve the final command output. When this functionality is mixed with built in commands, the user is provided with an environment that can maximize efficiency. Shell redirection is the action of sending the output or the input of a command into another command or into a file. To capture the output of the man:ls[1] command, for example, into a file, redirect the output: [source,shell] .... % ls > directory_listing.txt .... The directory contents will now be listed in `directory_listing.txt`. Some commands can be used to read input, such as man:sort[1]. To sort this listing, redirect the input: [source,shell] .... % sort < directory_listing.txt .... The input will be sorted and placed on the screen. To redirect that input into another file, one could redirect the output of man:sort[1] by mixing the direction: [source,shell] .... % sort < directory_listing.txt > sorted.txt .... In all of the previous examples, the commands are performing redirection using file descriptors. Every UNIX(R) system has file descriptors, which include standard input (stdin), standard output (stdout), and standard error (stderr). Each one has a purpose, where input could be a keyboard or a mouse, something that provides input. Output could be a screen or paper in a printer. And error would be anything that is used for diagnostic or error messages. All three are considered I/O based file descriptors and sometimes considered streams. Through the use of these descriptors, the shell allows output and input to be passed around through various commands and redirected to or from a file. Another method of redirection is the pipe operator. The UNIX(R) pipe operator, "|" allows the output of one command to be directly passed or directed to another program. Basically, a pipe allows the standard output of a command to be passed as standard input to another command, for example: [source,shell] .... % cat directory_listing.txt | sort | less .... In that example, the contents of `directory_listing.txt` will be sorted and the output passed to man:less[1]. This allows the user to scroll through the output at their own pace and prevent it from scrolling off the screen. [[editors]] == Text Editors Most FreeBSD configuration is done by editing text files, so it is a good idea to become familiar with a text editor. FreeBSD comes with a few as part of the base system, and many more are available in the Ports Collection. A simple editor to learn is man:ee[1], which stands for easy editor. To start this editor, type `ee _filename_` where _filename_ is the name of the file to be edited. Once inside the editor, all of the commands for manipulating the editor's functions are listed at the top of the display. The caret (`^`) represents kbd:[Ctrl], so `^e` expands to kbd:[Ctrl+e]. To leave man:ee[1], press kbd:[Esc], then choose the "leave editor" option from the main menu. The editor will prompt to save any changes if the file has been modified. FreeBSD also comes with more powerful text editors, such as man:vi[1], as part of the base system. Other editors, like package:editors/emacs[] and package:editors/vim[], are part of the FreeBSD Ports Collection. These editors offer more functionality at the expense of being more complicated to learn. Learning a more powerful editor such as vim or Emacs can save more time in the long run. Many applications which modify files or require typed input will automatically open a text editor. To change the default editor, set the `EDITOR` environment variable as described in crossref:basics[shells, Shells]. [[basics-devices]] == Devices and Device Nodes A device is a term used mostly for hardware-related activities in a system, including disks, printers, graphics cards, and keyboards. When FreeBSD boots, the majority of the boot messages refer to devices being detected. A copy of the boot messages is saved to `/var/run/dmesg.boot`. Each device has a device name and number. For example, `ada0` is the first SATA hard drive, while `kbd0` represents the keyboard. Most devices in FreeBSD must be accessed through special files called device nodes, which are located in `/dev`. [[basics-more-information]] == Manual Pages The most comprehensive documentation on FreeBSD is in the form of manual pages. Nearly every program on the system comes with a short reference manual explaining the basic operation and available arguments. These manuals can be viewed using `man`: [source,shell] .... % man command .... where _command_ is the name of the command to learn about. For example, to learn more about man:ls[1], type: [source,shell] .... % man ls .... Manual pages are divided into sections which represent the type of topic. In FreeBSD, the following sections are available: . User commands. . System calls and error numbers. . Functions in the C libraries. . Device drivers. . File formats. . Games and other diversions. . Miscellaneous information. . System maintenance and operation commands. . System kernel interfaces. In some cases, the same topic may appear in more than one section of the online manual. For example, there is a `chmod` user command and a `chmod()` system call. To tell man:man[1] which section to display, specify the section number: [source,shell] .... % man 1 chmod .... This will display the manual page for the user command man:chmod[1]. References to a particular section of the online manual are traditionally placed in parenthesis in written documentation, so man:chmod[1] refers to the user command and man:chmod[2] refers to the system call. If the name of the manual page is unknown, use `man -k` to search for keywords in the manual page descriptions: [source,shell] .... % man -k mail .... This command displays a list of commands that have the keyword "mail" in their descriptions. This is equivalent to using man:apropos[1]. To read the descriptions for all of the commands in `/usr/sbin`, type: [source,shell] .... % cd /usr/sbin % man -f * | more .... or [source,shell] .... % cd /usr/sbin % whatis * |more .... [[basics-info]] === GNU Info Files FreeBSD includes several applications and utilities produced by the Free Software Foundation (FSF). In addition to manual pages, these programs may include hypertext documents called `info` files. These can be viewed using man:info[1] or, if package:editors/emacs[] is installed, the info mode of emacs. To use man:info[1], type: [source,shell] .... % info .... For a brief introduction, type `h`. For a quick command reference, type `?`. diff --git a/documentation/content/en/books/handbook/bsdinstall/_index.adoc b/documentation/content/en/books/handbook/bsdinstall/_index.adoc index 577c0114e0..9b9c4921be 100644 --- a/documentation/content/en/books/handbook/bsdinstall/_index.adoc +++ b/documentation/content/en/books/handbook/bsdinstall/_index.adoc @@ -1,1293 +1,1293 @@ --- title: Chapter 2. Installing FreeBSD part: Part I. Getting Started prev: books/handbook/introduction next: books/handbook/basics description: Guide about how to install FreeBSD, the minimum hardware requirements and supported architectures, how to create the installation media, etc tags: ["bsdinstall", "installing FreeBSD", "requirements", "tutorial", "guide"] showBookMenu: true weight: 4 params: path: "/books/handbook/bsdinstall/" --- [[bsdinstall]] = Installing FreeBSD :doctype: book :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumoffset: 2 :partnums: :source-highlighter: rouge :experimental: :images-path: books/handbook/bsdinstall/ ifdef::env-beastie[] ifdef::backend-html5[] :imagesdir: ../../../../images/{images-path} endif::[] ifndef::book[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] toc::[] endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] toc::[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [[bsdinstall-synopsis]] == Synopsis FreeBSD supports different architectures including amd64, ARM(R), RISC-V(R), and PowerPC(R). Depending on the architecture and platform, different images can be link:https://www.freebsd.org/where/[downloaded] to install or directly run FreeBSD. The image types are: * Virtual Machine disk images, such as `qcow2`, `vmdk`, `vhd`, and raw device images. These are not installation images, but images that have FreeBSD preinstalled and ready for post-installation tasks. Virtual machine images are also commonly used in cloud environments. * SD card images, for embedded systems such as Raspberry Pi. These files must be uncompressed and written as a raw image to an SD card, from which the board will boot. * Installation images to boot from an ISO or USB device to install FreeBSD on a drive for the usual desktop, laptop, or server system. The rest of this chapter describes the third case, explaining how to install FreeBSD using the text-based installation program named bsdinstall. There may be minor differences between the installer and what is shown here, so use this chapter as a general guide rather than as a set of literal instructions. Read this chapter to learn: * How to obtain FreeBSD images and create FreeBSD installation media. * How to start bsdinstall. * The questions bsdinstall will ask, what they mean, and how to answer them. * How to troubleshoot a failed installation. * How to access a live version of FreeBSD before committing to an installation. [[bsdinstall-hardware]] == Minimum Hardware Requirements The hardware requirements to install FreeBSD vary by architecture and version. Hardware architectures and devices supported by a FreeBSD release are listed on the link:https://www.FreeBSD.org/releases/[FreeBSD Release Information] page. The link:https://www.FreeBSD.org/where/[FreeBSD download page] also has recommendations for choosing the correct image for different architectures. [[bsdinstall-pre]] == Pre-Installation Tasks Once it has been determined that the system meets the minimum hardware requirements for installing FreeBSD, the installation file should be downloaded and the installation media prepared. [TIP] ==== Consider using crossref:virtualization[virtualization,virtualization] when wanting to use FreeBSD on a system that already has another operating system installed. ==== Before moving on to the installation, check that the system is ready by verifying the items in this checklist: [.procedure] ==== . *Back Up Important Data* + Before installing any operating system, *always* backup all important data first. Do not store the backup on the system being installed. Instead, save the data to a removable disk such as a USB drive, another system on the network, or an online backup service. Test the backup before starting the installation to make sure it contains all of the needed files. Once the installer formats the system's disk, all data stored on that disk will be lost. . *Decide Where to Install FreeBSD* + If FreeBSD will be the only operating system installed, this step can be skipped. But if FreeBSD will share the disk with another operating system, decide which disk or partition will be used for FreeBSD. + In the i386 and amd64 architectures, disks can be divided into multiple partitions using one of two partitioning schemes. A traditional _Master Boot Record_ (MBR) holds a partition table defining up to four _primary partitions_. For historical reasons, FreeBSD calls these primary partition _slices_. One of these primary partitions can be made into an _extended partition_ containing multiple _logical partitions_. The _GUID Partition Table_ (GPT) is a newer and simpler method of partitioning a disk. Common GPT implementations allow up to 128 partitions per disk, eliminating the need for logical partitions. + The FreeBSD boot loader requires either a primary or GPT partition. If all of the primary or GPT partitions are already in use, one must be freed for FreeBSD. To create a partition without deleting existing data, use a partition resizing tool to shrink an existing partition and create a new partition using the freed space. + An alternative to modifying the system's existing disk partitions is to use crossref:virtualization[virtualization,virtualization], which allows multiple operating systems to run at the same time without having to alter partitions. + A variety of free and commercial partition resizing tools are listed at link:https://en.wikipedia.org/wiki/List_of_disk_partitioning_software[List of disk partitioning software wikipedia entry]. link:https://gparted.org/livecd.php[GParted Live] is a free live CD which includes the GParted partition editor. + [WARNING] ====== When used properly, disk shrinking utilities can safely create space for creating a new partition. Since the possibility of selecting the wrong partition exists, always backup any important data and verify the integrity of the backup before modifying disk partitions. ====== + Disk partitions containing different operating systems make it possible to install multiple operating systems on one computer. . *Collect Network Information* + Some FreeBSD installation methods require a network connection in order to download the installation files. After any installation, the installer will offer to setup the system's network interfaces. + If the network has a DHCP server, it can be used to provide automatic network configuration. If DHCP is not available, the following network information for the system must be obtained from the local network administrator or Internet service provider: + [[bsdinstall-collect-network-information]] Required Network Information .. IP address .. Subnet mask .. IP address of default gateway .. Domain name of the network .. IP addresses of the network's DNS servers . *Check for FreeBSD Errata* + Although the FreeBSD Project strives to ensure that each release of FreeBSD is as stable as possible, bugs occasionally creep into the process. On very rare occasions those bugs affect the installation process. As these problems are discovered and fixed, they are noted in the FreeBSD Errata page of each version. Check the errata before installing to make sure that there are no problems that might affect the installation. + Information and errata for all the releases can be found on the link:https://www.FreeBSD.org/releases/[FreeBSD Release Information] page. ==== [[bsdinstall-installation-media]] === Prepare the Installation Media The FreeBSD installer is not an application that can be run from within another operating system. Instead, download a FreeBSD installation file, burn it to the media associated with its file type and size (CD, DVD, or USB), and boot the system to install from the inserted media. FreeBSD installation files are available at the link:https://www.FreeBSD.org/where/[FreeBSD download page]. Each installation file's name includes the release version of FreeBSD, the architecture, and the type of file. Installation files are available in several formats, compressed with man:xz[1] or uncompressed. The formats vary depending on computer architecture and media type. Installation file types: * `*-bootonly.iso*`: This is the smallest installation file as it only contains the installer. A working Internet connection is required during installation as the installer will download the files it needs to complete the FreeBSD installation. This file should be burned to optical media. * `*-disc1.iso*`: This file contains all of the files needed to install FreeBSD, its source, and the Ports Collection. This file should be burned to optical media. * `*-dvd1.iso*`: This file contains all of the files needed to install FreeBSD, its source, and the Ports Collection. It also contains a set of popular binary packages for installing a window manager and some applications so that a complete system can be installed from media without requiring a connection to the Internet. This file should be burned to optical media. * `*-memstick.img*`: This file contains all of the files needed to install FreeBSD, its source, and the Ports Collection. Write this file to a USB stick as shown in crossref:bsdinstall[bsdinstall-usb, Writing an Image File to USB]. * `*-mini-memstick.img*`: Like `*-bootonly.iso*`, does not include installation files, but downloads them as needed. A working internet connection is required during installation. It should be written to a USB stick as shown in crossref:bsdinstall[bsdinstall-usb, Writing an Image File to USB]. After downloading the image file, download at least one _checksum_ file from the same directory. There are two _checksum_ files available, named after the release number and the architecture name. For example: `CHECKSUM.SHA256-FreeBSD-{rel-latest}-RELEASE-amd64` and `CHECKSUM.SHA512-FreeBSD-{rel-latest}-RELEASE-amd64`. After downloading one of the files (or both), calculate the _checksum_ for the image file and compare it with the one shown in the _checksum_ file. Note that comparing the calculated _checksum_ against the correct file is needed, as they correspond to two different algorithms: SHA256 and SHA512. FreeBSD provides man:sha256[1] and man:sha512[1] that can be used for calculating the _checksum_. Other operating systems have similar programs. Verifying the _checksum_ in FreeBSD can be done automatically using man:sha256sum[1] (and man:sha512sum[1]) by executing: [source,shell,subs=attributes] .... % sha256sum -c CHECKSUM.SHA256-FreeBSD-{rel-latest}-RELEASE-amd64 --ignore-missing FreeBSD-{rel-latest}-RELEASE-amd64-dvd1.iso: OK .... The checksums must match exactly. If the checksums do not match, the image file is corrupt and must be downloaded again. [[bsdinstall-usb]] ==== Writing an Image File to USB The `\*memstick.img` file is an _image_ of the complete contents of a memory stick. It _cannot_ be copied to the target device as a file. Several applications are available for writing the `*.img` to a USB stick. This section describes two of these utilities. [IMPORTANT] ==== Before proceeding, back up any important data on the USB stick. This procedure will erase the existing data on the stick. ==== [[bsdinstall-usb-dd]] [.procedure] ==== *Procedure. Using `dd` to write the image* + [WARNING] ====== This example uses `/dev/da0` as the target device where the image will be written. Be *very careful* that the correct device is used as this command will destroy the existing data on the specified target device. ====== . The command-line utility is available on BSD, Linux(R), and Mac OS(R) systems. To burn the image using `dd`, insert the USB stick and determine its device name. Then, specify the name of the downloaded installation file and the device name for the USB stick. This example burns the amd64 installation image to the first USB device on an existing FreeBSD system. + [source,shell,subs=attributes] .... # dd if=FreeBSD-{rel-latest}-RELEASE-amd64-memstick.img of=/dev/da0 bs=1M conv=sync .... + If this command fails, verify that the USB stick is not mounted and that the device name is for the disk, not a partition. + Some operating systems might require this command to be run with man:sudo[8]. The man:dd[1] syntax varies slightly across different platforms; for example, Mac OS(R) requires a lower-case `bs=1m`. Systems like Linux(R) might buffer writes. To force all writes to complete, use man:sync[8]. ==== [.procedure] ==== *Procedure. Using Windows(R) to Write the Image* + [WARNING] ====== Be sure to give the correct drive letter as the existing data on the specified drive will be overwritten and destroyed. ====== . *Obtaining Image Writer for Windows(R)* + Image Writer for Windows(R) is a free application that can correctly write an image file to a memory stick. Download it from https://sourceforge.net/projects/win32diskimager/[win32diskimager home page] and extract it into a folder. . *Writing the Image with Image Writer* + Double-click the Win32DiskImager icon to start the program. Verify that the drive letter shown under `Device` is the drive with the memory stick. Click the folder icon and select the image to be written to the memory stick. Click btn:[Save] to accept the image file name. Verify that everything is correct, and that no folders on the memory stick are open in other windows. When everything is ready, click btn:[Write] to write the image file to the memory stick. ==== [[bsdinstall-start]] == Starting the Installation [IMPORTANT] ==== By default, the installation will not make any changes to the disk(s) before the following message: [.programlisting] .... Your changes will now be written to disk. If you have chosen to overwrite existing data, it will be PERMANENTLY ERASED. Are you sure you want to commit your changes? .... The install can be exited at any time prior to this warning. If there is a concern that something is incorrectly configured, just turn the computer off before this point and no changes will be made to the system's disks. ==== This section describes how to boot the system from the installation media which was prepared using the instructions in crossref:bsdinstall[bsdinstall-installation-media, Prepare the Installation Media]. When using a bootable USB stick, plug in the USB stick before turning on the computer. When booting from CD or DVD, turn on the computer and insert the media at the first opportunity. How to configure the system to boot from the inserted media depends upon the architecture. [[bsdinstall-view-probe]] === FreeBSD Boot Loader Menu Once the system boots from the installation media, a menu similar to the following will be displayed: [[bsdinstall-newboot-loader-menu]] .FreeBSD Boot Loader Menu image::bsdinstall-newboot-loader-menu.png[FreeBSD boot loader menu] By default, the menu will wait ten seconds for user input before booting into the FreeBSD installer or, if FreeBSD is already installed, before booting into FreeBSD. To pause the boot timer in order to review the selections, press kbd:[Space]. To select an option, press its highlighted number, character, or key. The following options are available. * `Boot Multi User`: This will continue the FreeBSD boot process. If the boot timer has been paused, press kbd:[1], upper- or lower-case kbd:[B], or kbd:[Enter]. * `Boot Single User`: This mode can be used to fix an existing FreeBSD installation as described in crossref:boot[boot-singleuser,“Single-User Mode”]. Press kbd:[2] or the upper- or lower-case kbd:[S] to enter this mode. * `Escape to loader prompt`: This will boot the system into a repair prompt that contains a limited number of low-level commands. This prompt is described in crossref:boot[boot-loader,“Stage Three”]. Press kbd:[3] or kbd:[Esc] to boot into this prompt. * `Reboot`: Reboots the system. * `Cons`: Allow to continue the installation by `video`, `serial`, `Dual (serial primary)` or `Dual (Video primary)` * `Kernel`: Loads a different kernel. * `Boot Options`: Opens the menu shown in, and described under, crossref:bsdinstall[bsdinstall-boot-options-menu,FreeBSD Boot Options Menu]. [[bsdinstall-boot-options-menu]] .FreeBSD Boot Options Menu image::bsdinstall-boot-options-menu.png[Menu showing the different boot options supported] The boot options menu is divided into two sections. The first section can be used to either return to the main boot menu or to reset any toggled options back to their defaults. The next section is used to toggle the available options to `On` or `Off` by pressing the option's highlighted number or character. The system will always boot using the settings for these options until they are modified. Several options can be toggled using this menu: * `ACPI`: If the system hangs during boot, try toggling this option to `Off`. This option is only present when ACPI support is available but not required. * `Safe Mode`: If the system still hangs during boot even with `ACPI Support` set to `Off`, try setting this option to `On`. * `Single User`: Toggle this option to `On` to fix an existing FreeBSD installation as described in crossref:boot[boot-singleuser,“Single-User Mode”]. Once the problem is fixed, set it back to `Off`. * `Verbose`: Toggle this option to `On` to see more detailed messages during the boot process. This can be useful when troubleshooting a piece of hardware. After making the needed selections, press kbd:[1] or kbd:[Backspace] to return to the main boot menu, then press kbd:[Enter] to continue booting into FreeBSD. A series of boot messages will appear as FreeBSD carries out its hardware device probes and loads the installation program. Once the boot is complete, the welcome menu shown in crossref:bsdinstall[bsdinstall-choose-mode,Welcome Menu] will be displayed. [[bsdinstall-choose-mode]] .Welcome Menu image::bsdinstall-choose-mode.png[FreeBSD installation welcome menu] Press kbd:[Enter] to select the default of btn:[Install] to enter the installer. The rest of this chapter describes how to use this installer. Otherwise, use the right or left arrows or the colorized letter to select the desired menu item. The btn:[Shell] can be used to access a FreeBSD shell in order to use command line utilities to prepare the disks before installation. The btn:[Live CD] option can be used to try out FreeBSD before installing it. The live version is described in crossref:bsdinstall[using-live-cd, Using the Live CD]. [TIP] ==== To review the boot messages, including the hardware device probe, press the upper- or lower-case kbd:[S] and then kbd:[Enter] to access a shell. At the shell prompt, type `more /var/run/dmesg.boot` and use the space bar to scroll through the messages. When finished, type `exit` to return to the welcome menu. ==== [[using-bsdinstall]] == Using bsdinstall This section shows the order of the bsdinstall menus and the type of information that will be asked before the system is installed. Use the arrow keys to highlight a menu option, then kbd:[Space] to select or deselect that menu item. When finished, press kbd:[Enter] to save the selection and move onto the next screen. [[bsdinstall-keymap]] === Selecting the Keymap Menu Before starting the process, bsdinstall will load the keymap files as shown in crossref:bsdinstall[bsdinstall-keymap-loading,Keymap Loading]. [[bsdinstall-keymap-loading]] .Keymap Loading image::bsdinstall-keymap-loading.png[Keymap loading] After the keymaps have been loaded, bsdinstall displays the menu shown in crossref:bsdinstall[bsdinstall-keymap-10,Keymap Selection Menu]. Use the up and down arrows to select the keymap that most closely represents the mapping of the keyboard attached to the system. Press kbd:[Enter] to save the selection. [[bsdinstall-keymap-10]] .Keymap Selection Menu image::bsdinstall-keymap-10.png[Keymap selection menu showing all supported keyboards] [NOTE] ==== Pressing kbd:[Esc] will exit this menu and use the default keymap. If the choice of keymap is not clear, [.guimenuitem]#United States of America ISO-8859-1# is also a safe option. ==== In addition, when selecting a different keymap, the user can try the keymap and ensure it is correct before proceeding, as shown in crossref:bsdinstall[bsdinstall-keymap-testing,Keymap Testing Menu]. [[bsdinstall-keymap-testing]] .Keymap Testing Menu image::bsdinstall-keymap-testing.png[Keymap testing menu] [[bsdinstall-hostname]] === Setting the Hostname The next bsdinstall menu is used to set the hostname for the newly installed system. [[bsdinstall-config-hostname]] .Setting the Hostname image::bsdinstall-config-hostname.png[Setting the hostname] Type in a hostname that is unique for the network. It should be a fully-qualified hostname, such as `machine3.example.com`. [[bsdinstall-installation-type]] === Selecting Installation Type In the next menu bsdinstall will ask whether to install the base system using traditional distribution sets or the new package-based method. [[bsdinstall-choose-type]] .Selecting Installation Type image::bsdinstall-distributions-sets-pkgbase.png[Choice between "Distribution Sets" and "Packages (Tech Preview)"] Starting with FreeBSD 15.0, the installer offers two distinct approaches for laying down and later updating the base system. Both options install the same kernel and userland but differ fundamentally in how they are delivered and maintained over time. * `Distribution Sets` - The classic installation method used since the early days of the project. The base system is unpacked from a collection of compressed tarballs. Updates are performed exclusively with the man:freebsd-update[8] utility. This method is fully supported, stable, and remains the default for most installation media in the 15.x series. * `Packages (Tech Preview)` - Installs the base system as a set of individual packages from the `FreeBSD-base` repository. Once installed, the entire operating system—both the base and any third-party software—can be upgraded with a single `pkg upgrade` command. This method, known as `pkgbase`, unifies system management under the man:pkg[8] framework. [TIP] ==== The `Packages (Tech Preview)` option is offered for testing and early adoption. While it is expected to become the default in FreeBSD 16.0, users who prefer a conservative, time-tested update solution should select `Distribution Sets` for production environments during the 15.x lifecycle. ==== [[bsdinstall-components]] === Selecting Components to Install Next, bsdinstall will prompt to select optional components to install. [[bsdinstall-config-components]] .Selecting Components to Install -image::bsdinstall-config-components.png[Different components that can be installed. Example: base-dbg, lib32, ports, etc.] +image::bsdinstall-config-components.png["Different components that can be installed. Example: base-dbg, lib32, ports, etc."] Deciding which components to install will depend largely on the intended use of the system and the amount of disk space available. The FreeBSD kernel and userland, collectively known as the _base system_, are always installed. Depending on the architecture, some of these components may not appear: * `base-dbg` - Base tools like cat and ls, among many others, with debug symbols activated. * `kernel-dbg` - Kernel and modules with debug symbols activated. * `lib32-dbg` - Compatibility libraries for running 32-bit applications on a 64-bit version of FreeBSD with debug symbols activated. * `lib32` - Compatibility libraries for running 32-bit applications on a 64-bit version of FreeBSD. * `ports` - The FreeBSD Ports Collection is a collection of files which automates the downloading, compiling and installation of third-party software packages. crossref:ports[ports,Installing Applications: Packages and Ports] discusses how to use the Ports Collection. + [WARNING] ==== The installation program does not check for adequate disk space. Select this option only if sufficient hard disk space is available. The FreeBSD Ports Collection takes up about {ports-size} of disk space. ==== * `src` - The complete FreeBSD source code for both the kernel and the userland. Although not required for the majority of applications, it may be required to build device drivers, kernel modules, or some applications from the Ports Collection. It is also used for developing FreeBSD itself. The full source tree requires 1 GB of disk space and recompiling the entire FreeBSD system requires an additional 5 GB of space. * `tests` - FreeBSD Test Suite. [[bsdinstall-netinstall]] === Installing from the Network The menu shown in crossref:bsdinstall[bsdinstall-netinstall-notify,Installing from the Network] only appears when installing from a `-bootonly.iso` or `-mini-memstick.img`, as this installation media does not hold copies of the installation files. Since the installation files must be retrieved over a network connection, this menu indicates that the network interface must be configured first. If this menu is shown in any step of the process, remember to follow the instructions in crossref:bsdinstall[bsdinstall-config-network-dev, Configuring Network Interfaces]. [[bsdinstall-netinstall-notify]] .Installing from the Network image::bsdinstall-netinstall-files.png[Indicates that certain components have not been found and will be downloaded using the network.] [[bsdinstall-partitioning]] == Allocating Disk Space The next menu is used to determine the method for allocating disk space. [[bsdinstall-zfs-partmenu]] .Partitioning Choices -image::bsdinstall-zfs-partmenu.png[Shows the different partition options. Example: Manual, Shell, etc.] +image::bsdinstall-zfs-partmenu.png["Shows the different partition options. Example: Manual, Shell, etc."] bsdinstall gives the user four methods for allocating disk space: * `Auto (ZFS)` partitioning creates a root-on-ZFS system with optional GELI encryption support for _boot environments_. * `Auto (UFS)` partitioning automatically sets up the disk partitions using the `UFS` file system. * `Manual` partitioning allows advanced users to create customized partitions from menu options. * `Shell` opens a shell prompt where advanced users can create customized partitions using command-line utilities like man:gpart[8], man:fdisk[8], and man:bsdlabel[8]. This section describes what to consider when laying out the disk partitions. It then demonstrates how to use the different partitioning methods. [[configtuning-initial]] === Designing the Partition Layout The default partition layout for file systems includes one file system for the entire system. When using `UFS` it may be worth considering the use of multiple file systems with sufficient disk space or multiple disks available. When laying out file systems, remember that hard drives transfer data faster from the outer tracks to the inner. Thus, smaller and heavier-accessed file systems should be closer to the outside of the drive, while larger partitions like `/usr` should be placed toward the inner parts of the disk. It is a good idea to create partitions in an order similar to: `/`, swap, `/var`, and `/usr`. The size of the `/var` partition reflects the intended machine's usage. This partition is used to hold mailboxes, log files, and printer spools. Mailboxes and log files can grow to unexpected sizes depending on the number of users and how long log files are kept. On average, most users rarely need more than about a gigabyte of free disk space in `/var`. [NOTE] ==== Sometimes, a lot of disk space is required in `/var/tmp`. When new software is installed, the packaging tools extract a temporary copy of the packages under `/var/tmp`. Large software packages, like Firefox or LibreOffice may be tricky to install if there is not enough disk space under `/var/tmp`. ==== The `/usr` partition holds many of the files which support the system, including the FreeBSD Ports Collection and system source code. At least 2 gigabytes of space is recommended for this partition. Also, note that home directories for users are placed in `/usr/home` by default, but can be placed on another partition. By default, `/home` is a symbolic link to `/usr/home`. When selecting partition sizes, keep the space requirements in mind. Running out of space in one partition while barely using another can be a hassle. As a rule of thumb, the swap partition should be about double the size of physical memory (RAM). Systems with minimal RAM (less for larger-memory configurations) may perform better with more swap. Configuring too little swap can lead to inefficiencies in the VM page scanning code and might create issues later if more memory is added. On larger systems with multiple SCSI disks or multiple IDE disks operating on different controllers, it is recommended that swap be configured on each drive, up to four drives. The swap partitions should be approximately the same size. The kernel can handle arbitrary sizes, but internal data structures scale to 4 times the largest swap partition. Keeping the swap partitions near the same size will allow the kernel to optimally stripe swap space across disks. Large swap sizes may elicit a kernel warning message about the total configured swap. The limit is raised by increasing the amount of memory allowed for keeping track of swap allocations, as instructed by the warning message. It might be easier to recover from a runaway program before being forced to reboot. By properly partitioning a system, fragmentation introduced in the smaller write-heavy partitions will not bleed over into the mostly read partitions. Keeping the write-loaded partitions closer to the disk's edge will increase I/O performance in the partitions where it occurs the most. While I/O performance in the larger partitions may be needed, shifting them more toward the edge of the disk will not lead to a significant performance improvement over moving `/var` to the edge. [[bsdinstall-part-guided]] === Guided Partitioning Using UFS When this method is selected, a menu will display the available disk(s). If multiple disks are connected, choose the one where FreeBSD is to be installed. [[bsdinstall-part-guided-disk]] .Selecting from Multiple Disks image::bsdinstall-part-guided-disk.png[Shows the list of disks on which FreeBSD can be installed] Once the disk is selected, the next menu prompts to install to either the entire disk or to create a partition using free space. If btn:[Entire Disk] is chosen, a general partition layout filling the whole disk is automatically created. Selecting btn:[Partition] creates a partition layout from the unused space on the disk. [[bsdinstall-part-entire-part]] .Selecting Entire Disk or Partition image::bsdinstall-part-entire-part.png[Menu asking the user if he wants to use all the available space on the disk or wants to make a partition] The next menu shows a list with the available partition scheme types. GPT is usually the most appropriate choice for amd64 computers. Older computers that are not compatible with GPT should use MBR. The other partition schemes are generally used for uncommon or older computers. More information is available in crossref:bsdinstall[partition-schemes,Partitioning Schemes]. [[bsdinstall-ufs-scheme]] .Select Partition Scheme image::bsdinstall-part-manual-partscheme.png[Menu showing the user the different the different types of partition that exist and requesting one of them] After the partition layout has been created, review it to ensure it meets the needs of the installation. Selecting btn:[Revert] will reset the partitions to their original values. Pressing btn:[Auto] will recreate the automatic FreeBSD partitions. Partitions can also be manually created, modified, or deleted. When the partitioning is correct, select btn:[Finish] to continue with the installation. [[bsdinstall-part-review]] .Review Created Partitions image::bsdinstall-part-review.png[Menu showing created partitions] Once the disks are configured, the next menu provides the last chance to make changes before the selected drives are formatted. If changes need to be made, select btn:[Back] to return to the main partitioning menu. btn:[Revert & Exit] exits the installer without making any changes to the drive. Otherwise, select btn:[Commit] to start the installation process. [[bsdinstall-ufs-final-confirmation]] .Final Confirmation image::bsdinstall-final-confirmation.png[Menu indicating to the user that all changes will be written to disk and informing that if he decides to continue the existing data will be permanently deleted.] To continue with the installation process, go to crossref:bsdinstall[bsdinstall-fetching-distribution, Fetching Distribution Files]. [[bsdinstall-part-manual]] === Manual Partitioning Selecting this method opens the partition editor: [[bsdinstall-part-manual-create]] .Manually Create Partitions image::bsdinstall-part-manual-create.png[Menu showing the Partition Editor.] Highlight the installation drive (`ada0` in this example) and select btn:[Create] to display a menu of available partition schemes: [[bsdinstall-part-manual-partscheme]] .Manually Create Partitions image::bsdinstall-part-manual-partscheme.png[Menu showing the different kind of partition schemes] GPT is usually the most appropriate choice for amd64 computers. Older computers that are not compatible with GPT should use MBR. The other partition schemes are generally used for uncommon or older computers. [[partition-schemes]] .Partitioning Schemes [cols="25h,~", frame="none", options="header"] |=== <| Abbreviation <| Description |APM |Apple Partition Map, used by PowerPC(R). |BSD |BSD label without an MBR, sometimes called _dangerously dedicated mode_ as non-BSD disk utilities may not recognize it. |GPT |link:https://en.wikipedia.org/wiki/GUID_Partition_Table[GUID Partition Table]. |MBR |link:https://en.wikipedia.org/wiki/Master_boot_record[Master Boot Record]. |=== After the partitioning scheme has been selected and created, select btn:[Create] again to create the partitions. The kbd:[Tab] key is used to give focus to the fields (after cycling through btn:[], btn:[], and btn:[]). [[bsdinstall-part-manual-addpart]] .Manually Create Partitions -image::bsdinstall-part-manual-addpart.png[Menu requesting type, size, mountpoint and label for the new partition.] +image::bsdinstall-part-manual-addpart.png["Menu requesting type, size, mountpoint and label for the new partition."] A standard FreeBSD GPT installation uses at least three partitions, including either UFS or ZFS: * `freebsd-boot` or `efi` - Holds the FreeBSD boot code. * `freebsd-ufs` - A FreeBSD UFS file system. * `freebsd-zfs` - A FreeBSD ZFS file system. More information about ZFS is available in crossref:zfs[zfs,The Z File System (ZFS)]. * `freebsd-swap` - FreeBSD swap space. Refer to man:gpart[8] for descriptions of the available GPT partition types. Multiple file system partitions can be created. Some people prefer a traditional layout with separate partitions for `/`, `/var`, `/tmp`, and `/usr`. [TIP] ==== Note that `/tmp` can be added later as a memory-based file system (man:tmpfs[5]) on systems with sufficient memory. ==== See crossref:bsdinstall[bsdinstall-part-manual-splitfs,Creating Traditional Split File System Partitions] for an example. The `Size` may be entered with common abbreviations: _K_ for kilobytes, _M_ for megabytes, or _G_ for gigabytes. [TIP] ==== Proper sector alignment provides the best performance, and making partition sizes even multiples of 4K bytes helps to ensure alignment on drives with either 512-byte or 4K-byte sectors. Generally, using partition sizes that are even multiples of 1M or 1G is the easiest way to make sure every partition starts at an even multiple of 4K. There is one exception: a _freebsd-boot_ partition for BIOS booting should be no larger than 512K due to legacy boot code limitations. This limitation does not apply to UEFI booting. ==== A `Mountpoint` is needed if the partition will contain a file system. If only a single UFS partition will be created, the mountpoint should be `/`. The `Label` is a name by which the partition will be known. Drive names or numbers can change if the drive is connected to a different controller or port, but the partition label does not change. Referring to labels instead of drive names and partition numbers in files like `/etc/fstab` makes the system more tolerant to hardware changes. GPT labels appear in `/dev/gpt/` when a disk is attached. Other partitioning schemes have different label capabilities and their labels appear in different directories in `/dev/`. [TIP] ==== Use a unique label on every partition to avoid conflicts from identical labels. A few letters from the computer's name, use, or location can be added to the label. For instance, use `labroot` or `rootfslab` for the UFS root partition on the computer named `lab`. ==== [[bsdinstall-part-manual-splitfs]] .Creating Traditional Split File System Partitions [example] ==== For a traditional partition layout where the `/`, `/var`, `/tmp`, and `/usr` directories are separate file systems on their own partitions, create a GPT partitioning scheme, then create the partitions as shown. Partition sizes shown are typical for a 20G target disk. If more space is available on the target disk, larger swap or `/var` partitions may be useful. Labels shown here are prefixed with `ex` for "example", but readers should use other unique label values as described above. By default, FreeBSD's `gptboot` expects the first UFS partition to be the `/` partition. [.informaltable] [cols="1,1,1,1", frame="none", options="header"] |=== | Partition Type | Size | Mountpoint | Label |`freebsd-boot` |`512K` | | |`freebsd-ufs` |`2G` |`/` |`exrootfs` |`freebsd-swap` |`4G` | |`exswap` |`freebsd-ufs` |`2G` |`/var` |`exvarfs` |`freebsd-ufs` |`1G` |`/tmp` |`extmpfs` |`freebsd-ufs` |accept the default (remainder of the disk) |`/usr` |`exusrfs` |=== ==== After the custom partitions have been created, select btn:[Finish] to continue with the installation and go to crossref:bsdinstall[bsdinstall-fetching-distribution, Fetching Distribution Files]. [[bsdinstall-part-zfs]] === Guided Partitioning Using Root-on-ZFS This partitioning mode only works with whole disks and will erase the contents of the entire disk. The main ZFS configuration menu offers a number of options to control the creation of the pool. [[bsdinstall-zfs-menu]] .ZFS Partitioning Menu image::bsdinstall-zfs-menu.png[Menu showing the different options to configure the ZFS pool] Here is a summary of the options in this menu: * `Install` - Proceed with the installation with the selected options. * `Pool Type/Disks` - Configure the `Pool Type` and the disk(s) that will constitute the pool. The automatic ZFS installer currently only supports the creation of a single top level vdev, except in stripe mode. To create more complex pools, use the instructions in crossref:bsdinstall[bsdinstall-part-shell, Shell Mode Partitioning] to create the pool. * `Rescan Devices` - Repopulate the list of available disks. * `Disk Info` - This menu can be used to inspect each disk, including its partition table and various other information such as the device model number and serial number, if available. * `Pool Name` - Establish the name of the pool. The default name is _zroot_. * `Force 4K Sectors?` - Force the use of 4K sectors. By default, the installer will automatically create partitions aligned to 4K boundaries and force ZFS to use 4K sectors. This is safe even with 512 byte sector disks, and has the added benefit of ensuring that pools created on 512 byte disks will be able to have 4K sector disks added in the future, either as additional storage space or as replacements for failed disks. Press the kbd:[Enter] key to chose to activate it or not. * `Encrypt Disks?` - Encrypting the disks allows the user to encrypt the disks using GELI. More information about disk encryption is available in crossref:disks[disks-encrypting-geli,“Disk Encryption with geli”]. Press the kbd:[Enter] key to choose whether to activate it or not. * `Partition Scheme` - Choose the partition scheme. GPT is the recommended option in most cases. Press the kbd:[Enter] key to chose between the different options. * `Swap Size` - Establish the amount of swap space. * `Mirror Swap?` - Whether to mirror the swap between the disks. Be aware that enabling mirror swap will break crash dumps. Press the kbd:[Enter] key to activate it or not. * `Encrypt Swap?` - Whether to encrypt the swap. This will encrypt the swap with a temporary key each time the system boots, and discards it on reboot. Press the kbd:[Enter] key to choose to activate it or not. More information about swap encryption in crossref:disks[swap-encrypting,“Encrypting Swap”]. * `ZFS Pool Options` - Specifies additional pool properties to apply when the ZFS root pool is created. More information about the options can be found in man:zpool-create[8] and man:zpoolprops[7]. Select kbd:[T] to configure the `Pool Type` and the disk(s) that will constitute the pool. [[bsdinstall-zfs-vdev_type]] .ZFS Pool Type -image::bsdinstall-zfs-vdev_type.png[Menu requesting the Virtual Device type. Ex: stripe, mirror, raidz1] +image::bsdinstall-zfs-vdev_type.png["Menu requesting the Virtual Device type. Ex: stripe, mirror, raidz1"] Here is a summary of the `Pool Type` that can be selected in this menu: * `stripe` - Striping provides maximum storage of all connected devices, but no redundancy. If just one disk fails the data on the pool is lost irrevocably. * `mirror` - Mirroring stores a complete copy of all data on every disk. Mirroring provides good read performance because data is read from all disks in parallel. Write performance is slower as the data must be written to all disks in the pool. Allows all but one disk to fail. This option requires at least two disks. * `raid10` - Striped mirrors. Provides the best performance, but the least storage. This option needs at least an even number of disks and a minimum of four disks. * `raidz1` - Single Redundant RAID. Allow one disk to fail concurrently. This option needs at least three disks. * `raidz2` - Double Redundant RAID. Allows two disks to fail concurrently. This option needs at least four disks. * `raidz3` - Triple Redundant RAID. Allows three disks to fail concurrently. This option needs at least five disks. Once a `Pool Type` has been selected, a list of available disks is displayed, and the user is prompted to select one or more disks to make up the pool. The configuration is then validated to ensure that enough disks are selected. If validation fails, select btn:[] to return to the list of disks or btn:[] to change the `Pool Type`. [[bsdinstall-zfs-disk_select]] .Disk Selection image::bsdinstall-zfs-disk_select.png[Menu requesting how many disks will be added to the pool] [[bsdinstall-zfs-vdev_invalid]] .Invalid Selection image::bsdinstall-zfs-vdev_invalid.png[Menu indicating that not enough disks have been selected] If one or more disks are missing from the list, or if disks were attached after the installer was started, select btn:[- Rescan Devices] to repopulate the list of available disks. [[bsdinstall-zfs-rescan-devices]] .Rescan Devices image::bsdinstall-zfs-rescan-devices.png[Device rescan] To avoid accidentally erasing the wrong disk, the btn:[- Disk Info] menu can be used to inspect each disk, including its partition table and various other information such as the device model number and serial number, if available. [[bsdinstall-zfs-disk_info]] .Analyzing a Disk image::bsdinstall-zfs-disk_info.png[Menu showing the information of the partitions.] Select kbd:[N] to configure the `Pool Name`. Enter the desired name, then select btn:[] to establish it or btn:[] to return to the main menu and leave the default name. [[bsdinstall-zfs-pool-name]] .Pool Name image::bsdinstall-zfs-pool-name.png[Menu requesting the name of the pool.] Select kbd:[S] to set the amount of swap. Enter the desired amount of swap, then select btn:[] to establish it or btn:[] to return to the main menu and let the default amount. [[bsdinstall-zfs-swap-amount]] .Swap Amount image::bsdinstall-zfs-swap-amount.png[Menu requesting the amount of swap memory] Once all options have been set to the desired values, select the btn:[>>> Install] option at the top of the menu. The installer then offers a last chance to cancel before the contents of the selected drives are destroyed to create the ZFS pool. [[bsdinstall-zfs-warning]] .Last Chance image::bsdinstall-zfs-warning.png[Menu indicating to the user that the data will be lost] If GELI disk encryption was enabled, the installer will prompt twice for the passphrase to be used to encrypt the disks. Initialization of the encryption then begins. [[bsdinstall-zfs-geli_password]] .Disk Encryption Password image::bsdinstall-zfs-geli_password.png[Menu requesting the password to encrypt the devices.] [[bsdinstall-zfs-init-encription]] .Initializing Encryption image::bsdinstall-zfs-init-encription.png[Menu showing that the encryption is initializing.] The installation then proceeds normally. To continue with the installation, go to crossref:bsdinstall[bsdinstall-fetching-distribution, Fetching Distribution Files]. [[bsdinstall-part-shell]] === Shell Mode Partitioning When creating advanced installations, the bsdinstall partitioning menus may not provide the level of flexibility required. Advanced users can select the btn:[Shell] option from the partitioning menu in order to manually partition the drives, create the file system(s), populate `/tmp/bsdinstall_etc/fstab`, and mount the file systems under `/mnt`. Once this is done, type `exit` to return to bsdinstall and continue the installation. [[bsdinstall-fetching-distribution]] == Fetching Distribution Files Installation time will vary depending on the distributions chosen, installation media, and speed of the computer. A series of messages will indicate the progress. First, the installer formats the selected disk(s) and initializes the partitions. Next, in the case of a `bootonly media` or `mini memstick`, it downloads the selected components: [[bsdinstall-distfile-fetching]] .Fetching Distribution Files image::bsdinstall-distfile-fetching.png[Menu showing the download of the different components.] Next, the integrity of the distribution files is verified to ensure they have not been corrupted during download or misread from the installation media: [[bsdinstall-distfile-verify]] .Verifying Distribution Files image::bsdinstall-distfile-verifying.png[Menu showing the verification of the different components.] Finally, the verified distribution files are extracted to the disk: [[bsdinstall-distfile-extract]] .Extracting Distribution Files image::bsdinstall-distfile-extracting.png[Menu showing the extraction of the different components.] Once all requested distribution files have been extracted, bsdinstall displays the first post-installation configuration screen. The available post-configuration options are described in the next section. [[bsdinstall-post]] == Network Interfaces, Accounts, Time Zone, Services and Hardening [[bsdinstall-post-root]] === Setting the `root` Password First, the `root` password must be set. While entering the password, the characters being typed are not displayed on the screen. The password must be entered twice to prevent typing errors. [[bsdinstall-post-set-root-passwd]] .Setting the `root` Password image::bsdinstall-post-root-passwd.png[Menu showing requesting the password for the root user.] [[bsdinstall-config-network-dev]] === Configuring Network Interfaces Next, a list of the network interfaces found on the computer is shown. Select the interface to configure. [[bsdinstall-configure-net-interface]] .Choose a Network Interface image::bsdinstall-configure-network-interface.png[Menu showing the different network interfaces to configure.] If an Ethernet interface is selected, the installer will skip ahead to the menu shown in crossref:bsdinstall[bsdinstall-configure-net-ipv4,Choose IPv4 Networking]. If a wireless network interface is chosen, the system will instead scan for wireless access points: [[bsdinstall-wireless-scan]] .Scanning for Wireless Access Points image::bsdinstall-configure-wireless-scan.png[Menu showing wireless network scanning.] Wireless networks are identified by a Service Set Identifier (SSID); a short, unique name given to each network. SSIDs found during the scan are listed, followed by a description of the encryption types available for that network. If the desired SSID does not appear in the list, select btn:[Rescan] to scan again. If the desired network still does not appear, check for problems with antenna connections or try moving the computer closer to the access point. Rescan after each change is made. [[bsdinstall-wireless-accesspoints]] .Choosing a Wireless Network image::bsdinstall-configure-wireless-accesspoints.png[Menu showing the different wireless networks to connect to.] Next, enter the encryption information for connecting to the selected wireless network. WPA2 encryption is strongly recommended over older encryption types such as WEP, which offer little security. If the network uses WPA2, input the password, also known as the Pre-Shared Key (PSK). For security reasons, the characters typed into the input box are displayed as asterisks. [[bsdinstall-wireless-wpa2]] .WPA2 Setup image::bsdinstall-configure-wireless-wpa2setup.png[Menu requesting the wireless network password.] Next, choose whether or not an IPv4 address should be configured on the Ethernet or wireless interface: [[bsdinstall-configure-net-ipv4]] .Choose IPv4 Networking image::bsdinstall-configure-network-interface-ipv4.png[Menu indicating if IPv4 wants to be configured for the selected interface.] There are two methods of IPv4 configuration. DHCP will automatically configure the network interface correctly and should be used if the network provides a DHCP server. Otherwise, the addressing information needs to be input manually as a static configuration. [NOTE] ==== Do not enter random network information as it will not work. If a DHCP server is not available, obtain the information listed in crossref:bsdinstall[bsdinstall-collect-network-information, Required Network Information] from the network administrator or Internet service provider. ==== If a DHCP server is available, select btn:[Yes] in the next menu to automatically configure the network interface. The installer will appear to pause for a minute or so as it finds the DHCP server and obtains the addressing information for the system. [[bsdinstall-net-ipv4-dhcp]] .Choose IPv4 DHCP Configuration image::bsdinstall-configure-network-interface-ipv4-dhcp.png[Menu indicating if DHCP wants to be configured for the selected interface.] If a DHCP server is not available, select btn:[No] and input the following addressing information in this menu: [[bsdinstall-net-ipv4-static]] .IPv4 Static Configuration image::bsdinstall-configure-network-interface-ipv4-static.png[Menu requesting data to configure IPv4 network.] * `IP Address` - The IPv4 address assigned to this computer. The address must be unique and not already in use by another device on the local network. * `Subnet Mask` - The subnet mask for the network. * `Default Router` - The IP address of the network's default gateway. The next screen will ask if the interface should be configured for IPv6. If IPv6 is available and desired, choose btn:[Yes] to select it. [[bsdinstall-net-ipv6]] .Choose IPv6 Networking image::bsdinstall-configure-network-interface-ipv6.png[Menu indicating if IPv6 wants to be configured for the selected interface.] IPv6 also has two methods of configuration. StateLess Address AutoConfiguration (SLAAC) will automatically request the correct configuration information from a local router. Refer to https://tools.ietf.org/html/rfc4862[rfc4862] for more information. Static configuration requires manual entry of network information. If an IPv6 router is available, select btn:[Yes] in the next menu to automatically configure the network interface. The installer will appear to pause for a minute or so as it finds the router and obtains the addressing information for the system. [[bsdinstall-net-ipv6-slaac]] .Choose IPv6 SLAAC Configuration image::bsdinstall-configure-network-interface-slaac.png[Menu indicating if SLAAC wants to be configured for the selected interface.] If an IPv6 router is not available, select btn:[No] and input the following addressing information in this menu: [[bsdinstall-net-ipv6-static]] .IPv6 Static Configuration image::bsdinstall-configure-network-interface-ipv6-static.png[Menu requesting data to configure IPv6 network.] * `IPv6 Address` - The IPv6 address assigned to this computer. The address must be unique and not already in use by another device on the local network. * `Default Router` - The IPv6 address of the network's default gateway. The last network configuration menu is used to configure the Domain Name System (DNS) resolver, which converts hostnames to and from network addresses. If DHCP or SLAAC was used to autoconfigure the network interface, the `Resolver Configuration` values may already be filled in. Otherwise, enter the local network's domain name in the `Search` field. `DNS #1` and `DNS #2` are the IPv4 and/or IPv6 addresses of the DNS servers. At least one DNS server is required. [[bsdinstall-net-dns-config]] .DNS Configuration image::bsdinstall-configure-network-ipv4-dns.png[Menu requesting data to configure DNS for the network.] Once the interface is configured, select a mirror site that is located in the same region of the world as the computer on which FreeBSD is being installed. Files can be retrieved more quickly when the mirror is close to the target computer, reducing installation time. [TIP] ==== Selecting `https://download.freebsd.org Main Site (GeoDNS, HTTPS)` or `ftp://download.freebsd.org Main Site (GeoDNS, FTP)` will automatically route to the nearest mirror. ==== [[bsdinstall-netinstall-mirror]] .Choosing a Mirror image::bsdinstall-netinstall-mirrorselect.png[Menu requesting a network mirror.] [[bsdinstall-timezone]] === Setting the Time Zone The next series of menus are used to determine the correct local time by selecting the geographic region, country, and time zone. Setting the time zone allows the system to automatically correct for regional time changes, such as daylight savings time, and perform other time zone related functions properly. The example shown here is for a machine located in the mainland time zone of Spain, Europe. The selections will vary according to the geographical location. [[bsdinstall-timezone-region]] .Select a Region image::bsdinstall-timezone-region.png[Menu requesting the timezone region.] The appropriate region is selected using the arrow keys and then pressing kbd:[Enter]. [[bsdinstall-timezone-country]] .Select a Country image::bsdinstall-timezone-country.png[Menu requesting the timezone country.] Select the appropriate country using the arrow keys and press kbd:[Enter]. [[bsdinstall-timezone-zone]] .Select a Time Zone image::bsdinstall-timezone-zone.png[Menu requesting the timezone zone.] The appropriate time zone is selected using the arrow keys and pressing kbd:[Enter]. [[bsdinstall-timezone-confirmation]] .Confirm Time Zone image::bsdinstall-timezone-confirm.png[Menu requesting confirmation of the selected timezone.] Confirm the abbreviation for the time zone is correct. [[bsdinstall-timezone-date]] .Select Date image::bsdinstall-timezone-date.png[Menu requesting the system date.] The appropriate date is selected using the arrow keys and then pressing btn:[Set Date]. Otherwise, the date selection can be skipped by pressing btn:[Skip]. [[bsdinstall-timezone-time]] .Select Time image::bsdinstall-timezone-time.png[Menu requesting the system time.] The appropriate time is selected using the arrow keys and then pressing btn:[Set Time]. Otherwise, the time selection can be skipped by pressing btn:[Skip]. [[bsdinstall-sysconf]] === Enabling Services The next menu is used to configure which system services will be started whenever the system boots. All of these services are optional. Only start the services that are needed for the system to function. [[bsdinstall-config-serv]] .Selecting Additional Services to Enable image::bsdinstall-config-services.png[Menu showing the different services available.] Here is a summary of the services that can be enabled in this menu: * `sshd` - The Secure Shell (SSH) daemon is used to remotely access a system over an encrypted connection. Only enable this service if the system should be available for remote logins. * `ntpd` - The Network Time Protocol (NTP) daemon for automatic clock synchronization. Enable this service when wanting to synchronise the system clock with a remote time server or pool. * `ntpd_sync_on_start` - Enabled, man:ntpd[8] is invoked with the `-g` flag during system startup, performing an immediate, one-time clock synchronization at boot time. * `local_unbound` - Enable the DNS local unbound. It is necessary to keep in mind that this is a configuration only meant for use as a local caching forwarding resolver. If the objective is to set up a resolver for the entire network, install package:dns/unbound[]. * `powerd` - System power control utility for power control and energy saving. * `moused` - Enable this service if the mouse will be used from the command-line system console. * `dumpdev` - Crash dumps are useful when debugging issues with the system, so users are encouraged to enable them. [[bsdinstall-hardening]] === Enabling Hardening Security Options The next menu is used to configure which security options will be enabled. All of these options are optional. But their use is encouraged. [[bsdinstall-hardening-options]] .Selecting Hardening Security Options image::bsdinstall-hardening.png[Menu shoring the different hardening security options.] Here is a summary of the options that can be enabled in this menu: * `hide_uids` - Hide processes running as other users (UID). This prevents unprivileged users from seeing running processes from other users. * `hide_gids` - Hide processes running as other groups (GID). This prevents unprivileged users from seeing running processes from other groups. * `hide_jail` - Hide processes running in jails. This prevents unprivileged users from seeing processes running inside jails. * `read_msgbuf` - Disable reading kernel message buffer for unprivileged users. Prevent unprivileged users from using man:dmesg[8] to view messages from the kernel's log buffer. * `proc_debug` - Disable process debugging facilities for unprivileged users. Disables a variety of unprivileged inter-process debugging services, including some procfs functionality, `ptrace()`, and `ktrace()`. Please note that this will also prevent debugging tools such as man:lldb[1], man:truss[1] and man:procstat[1], as well as some built-in debugging facilities in certain scripting languages like PHP. * `random_pid` - Randomize the PID of processes. * `clear_tmp` - Clean `/tmp` when the system starts up. * `disable_syslogd` - Disable opening the syslogd network socket. By default, FreeBSD runs syslogd in a secure way with `-s`. This prevents the daemon from listening for incoming UDP requests on port 514. With this option enabled, syslogd will instead run with `-ss`, which prevents syslogd from opening any port. For more information, see man:syslogd[8]. * `secure_console` - Make the command prompt request the `root` password when entering single-user mode. * `disable_ddtrace` - DTrace can run in a mode that affects the running kernel. Destructive actions may not be used unless explicitly enabled. Use `-w` to enable this option when using DTrace. For more information, see man:dtrace[1]. [[bsdinstall-addusers]] === Add Users The next menu prompts to create at least one user account. It is recommended to log into the system using a user account rather than as `root`. When logged in as `root`, there are essentially no limits or protection on what can be done. Logging in as a normal user is safer and more secure. Select btn:[Yes] to add new users. [[bsdinstall-add-user1]] .Add User Accounts image::bsdinstall-adduser1.png[Menu requesting if a user want to be added to the system.] Follow the prompts and input the requested information for the user account. The example shown in crossref:bsdinstall[bsdinstall-add-user2,Enter User Information] creates the `asample` user account. [[bsdinstall-add-user2]] .Enter User Information image::bsdinstall-adduser2.png[Menu requesting different information for the new user.] Here is a summary of the information to input: * `Username` - The name the user will enter to log in. A common convention is to use the first letter of the first name combined with the last name, as long as each username is unique for the system. The username is case sensitive and should not contain any spaces. * `Full name` - The user's full name. This can contain spaces and is used as a description for the user account. * `Uid` - User ID. This is typically left blank so the system automatically assigns a value. * `Login group` - The user's group. This is typically left blank to accept the default. * `Invite _user_ into other groups?` - Additional groups to which the user will be added as a member. If the user needs administrative access, type `wheel` here. * `Login class` - Typically left blank for the default. * `Shell` - Type in one of the listed values to set the interactive shell for the user. Refer to crossref:basics[shells,Shells] for more information about shells. * `Home directory` - The user's home directory. The default is usually correct. * `Home directory permissions` - Permissions on the user's home directory. The default is usually correct. * `Use password-based authentication?` - Typically `yes` so that the user is prompted to input their password at login. * `Use an empty password?` - Typically `no` as empty or blank passwords are insecure. * `Use a random password?` - Typically `no` so that the user can set their own password in the next prompt. * `Enter password` - The password for this user. Typed-in characters will not be shown on the screen. * `Enter password again` - The password must be typed again for verification. * `Lock out the account after creation?` - Typically `no` so that the user can log in. After entering all the details, a summary is shown for review. If a mistake was made, enter `no` to correct it. Once everything is correct, enter `yes` to create the new user. [[bsdinstall-add-user3]] .Exit User and Group Management image::bsdinstall-adduser3.png[Menu showing the information of the new user and requesting if everything is correct.] If there are more users to add, answer the `Add another user?` question with `yes`. Enter `no` to finish adding users and continue the installation. For more information on adding users and user management, see crossref:basics[users-synopsis,Users and Basic Account Management]. [[bsdinstall-final-conf]] === Final Configuration After everything has been installed and configured, a final chance is provided to modify settings. [[bsdinstall-final-config]] .Final Configuration -image::bsdinstall-finalconfiguration.png[Menu showing different options to perform before finishing the installation. Ex: Add user, Time Zone, etc.] +image::bsdinstall-finalconfiguration.png["Menu showing different options to perform before finishing the installation. Ex: Add user, Time Zone, etc."] Use this menu to make any changes or to do any additional configuration before completing the installation. * `Add User` - Described in crossref:bsdinstall[bsdinstall-addusers, Add Users]. * `Root Password` - Described in crossref:bsdinstall[bsdinstall-post-root, Setting the `root` Password]. * `Hostname` - Described in crossref:bsdinstall[bsdinstall-hostname, Setting the Hostname]. * `Network` - Described in crossref:bsdinstall[bsdinstall-config-network-dev, Configuring Network Interfaces]. * `Services` - Described in crossref:bsdinstall[bsdinstall-sysconf, Enabling Services]. * `System Hardening` - Described in crossref:bsdinstall[bsdinstall-hardening, Enabling Hardening Security Options]. * `Time Zone` - Described in crossref:bsdinstall[bsdinstall-timezone, Setting the Time Zone]. * `Firmware` - Download and install required firmware for system components such as Wi-Fi or graphics cards. * `Handbook` - Download and install the FreeBSD Handbook. Once configuration is complete, select btn:[Exit]. [[bsdinstall-final-modification-shell]] .Manual Configuration image::bsdinstall-final-modification-shell.png[Menu showing that the installation has finished. And asking if a shell to make manual changes should open.] bsdinstall will prompt for any additional configuration that needs to be done before rebooting into the new system. Select btn:[Yes] to exit to a shell within the new system or btn:[No] to proceed to the last step of the installation. [[bsdinstall-final-main]] .Complete the Installation image::bsdinstall-mainexit.png[Menu showing that the installation has finished and asking whether to reboot the system or access the Live CD.] If further configuration or special setup is needed, select btn:[Live CD] to boot the install media into Live CD mode. If the installation is complete, select btn:[Reboot] to reboot the computer and start the new FreeBSD system. Do not forget to remove the FreeBSD install media or the computer might boot from it again. As FreeBSD boots, informational messages are displayed. After the system finishes booting, a login prompt is displayed. At the `login:` prompt, enter the username added during the installation. Avoid logging in as `root`. Refer to crossref:basics[users-superuser,The Superuser Account] for instructions on how to become the superuser when administrative access is needed. The messages that appear during boot can be reviewed by pressing kbd:[Scroll-Lock] to turn on the scroll-back buffer. The kbd:[PgUp], kbd:[PgDn], and arrow keys can be used to scroll back through the messages. When finished, press kbd:[Scroll-Lock] again to unlock the display and return to the console. To review these messages once the system has been up for some time, type `less /var/run/dmesg.boot` from a command prompt. Press kbd:[q] to return to the command line after viewing. If sshd was enabled in crossref:bsdinstall[bsdinstall-config-serv,Selecting Additional Services to Enable], the first boot might be a bit slower as the system generates SSH host keys. Subsequent boots will be faster. The fingerprints of the keys are then displayed as in the following example: [source,shell] .... Generating public/private rsa1 key pair. Your identification has been saved in /etc/ssh/ssh_host_key. Your public key has been saved in /etc/ssh/ssh_host_key.pub. The key fingerprint is: 10:a0:f5:af:93:ae:a3:1a:b2:bb:3c:35:d9:5a:b3:f3 root@machine3.example.com The key's randomart image is: +--[RSA1 1024]----+ | o.. | | o . . | | . o | | o | | o S | | + + o | |o . + * | |o+ ..+ . | |==o..o+E | +-----------------+ Generating public/private dsa key pair. Your identification has been saved in /etc/ssh/ssh_host_dsa_key. Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub. The key fingerprint is: 7e:1c:ce:dc:8a:3a:18:13:5b:34:b5:cf:d9:d1:47:b2 root@machine3.example.com The key's randomart image is: +--[ DSA 1024]----+ | .. . .| | o . . + | | . .. . E .| | . . o o . . | | + S = . | | + . = o | | + . * . | | . . o . | | .o. . | +-----------------+ Starting sshd. .... Refer to crossref:security[openssh,"OpenSSH"] for more information about fingerprints and SSH. FreeBSD does not install a graphical environment by default. Refer to crossref:x11[x11,The X Window System] for more information about installing and configuring a graphical window manager. Proper shutdown of a FreeBSD computer helps protect data and hardware from damage. _Do not turn off the power before the system has been properly shut down!_ If the user is a member of the `wheel` group, become the superuser by typing `su` at the command line and entering the `root` password. Then, type `shutdown -p now` and the system will shut down cleanly, and, if the hardware supports it, turn itself off. [[bsdinstall-install-trouble]] == Troubleshooting This section covers basic installation troubleshooting, such as common problems people have reported. Check the Hardware Notes listed on the link:https://www.FreeBSD.org/releases/[FreeBSD Release Information] page for the version of FreeBSD to make sure the hardware is supported. [NOTE] ==== Some installation problems can be avoided or alleviated by updating the firmware on various hardware components, most notably the motherboard. Motherboard firmware is usually referred to as the BIOS. Most motherboard and computer manufacturers have a website for upgrades and upgrade information. Manufacturers generally advise against upgrading the motherboard BIOS unless there is a good reason for doing so, like a critical update. The upgrade process _can_ go wrong, leaving the BIOS incomplete and the computer inoperative. ==== If the system hangs while probing hardware during boot or behaves strangely during the installation process, ACPI may be the culprit. FreeBSD makes extensive use of the system ACPI service on the i386 and amd64 platforms to aid in system configuration if it is detected during boot. Unfortunately, some bugs still exist in both the ACPI driver and within system motherboards and BIOS firmware. ACPI can be disabled by setting the `hint.acpi.0.disabled` hint in the third stage boot loader: [source,shell] .... set hint.acpi.0.disabled="1" .... This is reset each time the system is booted, so it is necessary to add `hint.acpi.0.disabled="1"` to the file `/boot/loader.conf`. More information about the boot loader can be found in crossref:boot[boot-synopsis,“Synopsis”]. [[using-live-cd]] == Using the Live CD The welcome menu of bsdinstall, shown in crossref:bsdinstall[bsdinstall-choose-mode,Welcome Menu], provides a btn:[Live CD] option. This is useful for those who are still wondering whether FreeBSD is the right operating system for them and want to test some of the features before installing. The following points should be noted before using the btn:[Live CD]: * To gain access to the system, authentication is required. The username is `root` and the password is blank. * As the system runs directly from the installation media, performance will be significantly slower than that of a system installed on a hard disk. * This option only provides a command prompt and not a graphical interface. diff --git a/documentation/content/en/books/handbook/containers/_index.adoc b/documentation/content/en/books/handbook/containers/_index.adoc index 1c7b21bcb0..b00fd470f2 100644 --- a/documentation/content/en/books/handbook/containers/_index.adoc +++ b/documentation/content/en/books/handbook/containers/_index.adoc @@ -1,1052 +1,1053 @@ --- title: Chapter 18. OCI Containers part: Part III. System Administration prev: books/handbook/security next: books/handbook/mac description: OCI Containers provide an industry-standard way to describe, distribute, and run container-based workloads tags: ["containers", "oci"] showBookMenu: true weight: 21 params: path: "/books/handbook/containers/" --- [[containers]] = OCI Containers :doctype: book :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumoffset: 18 :partnums: :source-highlighter: rouge :experimental: :images-path: books/handbook/containers/ ifdef::env-beastie[] ifdef::backend-html5[] :imagesdir: ../../../../images/{images-path} endif::[] ifndef::book[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] toc::[] endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] toc::[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [[containers-synopsis]] == Synopsis The https://opencontainers.org/[Open Container Initiative], commonly referred to as `+OCI+`, provides a vendor and OS-agnostic way to describe, distribute, and run containers. The OCI specifications provide these in a way that can be used on many different operating systems, including FreeBSD. The underlying virtualization technology is still FreeBSD jails, with the same feature set, but OCI tooling enables additional ways of working, and constructing, container-based workloads. https://www.freebsd.org/releases/14.3R/announce/[14.3-RELEASE] and upwards, including https://download.freebsd.org/snapshots/OCI-IMAGES/[snapshots], now include OCI-compatible images, and the https://podman.io/[Podman] toolkit on FreeBSD is ready to use them, on both amd64 and arm64 architectures. For FreeBSD users familiar with jails, there is a loose analogy: * FreeBSD's `+base.txz+` tarball is an example of a container image. * the `+jail.conf+` file describes the desired container properties, or `+Containerfile+`. * use the `+jail ..+` command to run a container, given a filesystem path, with the `+podman+` suite of tools. By importing this container stack, FreeBSD users both benefit from common tooling, but also enjoy wide support across public and private container registries, and container-specific tooling and services. In the https://download.freebsd.org/releases/OCI-IMAGES/{rel-latest}-RELEASE/aarch64/Latest/[aarch64] and https://download.freebsd.org/releases/OCI-IMAGES/{rel-latest}-RELEASE/amd64/Latest/[amd64] download directories, you'll see official OCI-format images. The naming may be a little confusing at first, but should make sense once you start using them. The same images are also available through common public container registries, including https://hub.docker.com/u/freebsd[Docker Hub], and https://github.com/orgs/freebsd/packages[Github Container Registry], but for the strongest chain of trust, you should fetch your image directly from https://download.freebsd.org/releases[Official FreeBSD Releases], and import them to your local system. Each image comprises a subset of a standard FreeBSD `+base.txz+` release tarball, for various use cases, and the usual FreeBSD `+CHECKSUM.*+` files, that can be verified against the PGP-signed release announcement. This gives a very strong chain of provenance, directly verifiable from the FreeBSD release team. [source,display,subs="verbatim,attributes"] ---- CHECKSUM.SHA256 CHECKSUM.SHA512 FreeBSD-{rel-latest}-RELEASE-amd64-container-image-static.txz FreeBSD-{rel-latest}-RELEASE-amd64-container-image-dynamic.txz FreeBSD-{rel-latest}-RELEASE-amd64-container-image-runtime.txz FreeBSD-{rel-latest}-RELEASE-amd64-container-image-notoolchain.txz FreeBSD-{rel-latest}-RELEASE-amd64-container-image-toolchain.txz ---- [[containers-naming-tagging]] == Container Image Naming and Tagging === Introduction FreeBSD's official container images are built from base system packages, themselves built during the FreeBSD release process, and published to public registries. This guide explains how images are named and tagged, helping you choose the right image for your needs, and ensuring you understand the implications of each choice, as new images are published, and in some cases, mutable tags are amended. This naming convention aligns with the new base system package naming scheme, giving clear provenance between container images and the corresponding FreeBSD releases. [[containers-image-types]] === Available Image Types Five types of FreeBSD container images are available, for `+amd64+` and `+aarch64+` architectures. [[containers-freebsd-static]] ==== `+freebsd-static+` The static image is intended as a base image, for a workload which is entirely statically linked. It contains no libraries, nor binaries, just the supporting files that most applications of this nature require. * public TLS certificates * minimal password file * minimal termcap * timezone database Note that it has, by design, a lean footprint, to make a security compromise of the container less useful to the attacker. There's no UNIX shell, no command-line tools, no dynamic libraries, nor package manager. It is the smallest image provided by the FreeBSD project. [[containers-freebsd-dynamic]] ==== `+freebsd-dynamic+` The dynamic image uses the static image as a parent layer, and supports using shared libraries, including `+libc+`. Most FreeBSD software should run without issue with this image, with minor changes. It doesn't have a shell, rc system, nor a package manager. These limitations are additional security, making it awkward for attackers in a compromised container to move laterally, or make use of tools that were never installed. [[containers-freebsd-runtime]] ==== `+freebsd-runtime+` Again, runtime builds on the preceding dynamic layer, and finally adds the minimum that a user would expect - a UNIX shell, rc system, and the package manager. It is the ideal base image for porting existing applications with a minimum of changes. Users will need to include additional FreeBSD base system libraries, as well as additional packages from the Ports tree. This is the closest to a typical FreeBSD system, including the man:pkg[8] tool, allowing users to install, or do, almost anything, similar to a non-containerised system. [[containers-freebsd-notoolchain]] ==== `+freebsd-notoolchain+` This base image contains almost all tools one would expect on a typical FreeBSD system, excluding those that are directly hardware-related, and thus not generally useful within a container, and the compiler and related toolchain, as it is quite large. [[containers-freebsd-toolchain]] ==== `+freebsd-toolchain+` The Toolchain base image is the sum of all preceding images, including a full compiler and toolchain. It is generally possible to compile almost any software for FreeBSD in the same way as a normal non-jailed FreeBSD system. All images follow a consistent naming pattern, derived from the FreeBSD release they are based upon. [[containers-tag-structure]] === Image Tag Structure [[containers-immutable-tags]] ==== Immutable Tags Immutable tags never change and are ideal for production systems where you need stability and predictability. These are the most common tags used by the release process. They will not change, even after FreeBSD security patches, or errata notices. They are ideal for base images for software deployments where a high degree of reproducibility is expected, even as a trade-off against more pro-active security patching. * `+major.minor+` (e.g., `+14.4+`): Points to a specific FreeBSD RELEASE version * `+major.minor.pX+` (e.g., `+14.4p1+`): Points to a specific patch level of a RELEASE * `+major.snapYYYYMMDDHHMMSS+` (e.g., `+16.snap20260325035941+`): a snapshot build with timestamp [[containers-mutable-tags]] ==== Mutable Tags Mutable tags are updated over time and are ideal for production, or CI/CD systems that always want the latest updates, but still wish to align with FreeBSD ABI compatibility. * `+major+` (e.g., `+15+`) will always be the latest support RELEASE version along the 15.x stable ABI * `+major.snap+` (e.g., `+15.snap+`) follows the latest developer snapshot along the 15.x stable ABI train, will often be in advance of official releases, and carries a risk of breakage, incompatibility, or other unanticipated issues. This is the most mutable tag, and should be used with caution. They are exactly the same as using FreeBSD's STABLE or CURRENT snapshots, as they use those images as their source. === When to Use Each Tag Type ==== For Production Use immutable tags to ensure your environment stays consistent: * `+freebsd-runtime:15.0+` - pinned to FreeBSD 15.0-RELEASE When security patches are released, you must explicitly rebuild or update with a new image tag. ==== For Continuous Integration and Development Use mutable tags to automatically get the latest updates: * `+freebsd-runtime:15+` - always the latest official RELEASE in the 15.x series These additional mutable tags will follow the regular published snapshots of FreeBSD STABLE and CURRENT. Use these if you want to test against what subsequent future releases of FreeBSD may contain, and accept occasional breakage or unanticipated changes. * `+freebsd-runtime:14.snap+` - always the latest build from 14-STABLE branch * `+freebsd-runtime:15.snap+` - always the latest build from 15-STABLE branch * `+freebsd-runtime:16.snap+` - always the latest build from 16-CURRENT branch [[containers-registries]] == Official Registry Locations Architecture-independent images can be downloaded and directly imported into your own registry from the https://download.freebsd.org/releases[Official FreeBSD Releases] site, or alternatively, pulled from the FreeBSD project's https://hub.docker.com/u/freebsd[Docker Hub], or https://github.com/orgs/freebsd/packages[GitHub Container Registry]. -Both https://hub.docker.com/_/alpine/[Alpine Linux] and the https://hub.docker.com/_/debian/[Debian] project publish tagged and mutable images, using similar approaches. +// Escape only the first _ in a Docker Hub URL (/_/) so Asciidoctor does not treat it as an italic marker. +Both https://hub.docker.com/\_/alpine/[Alpine Linux] and the https://hub.docker.com/_/debian/[Debian] project publish tagged and mutable images, using similar approaches. [[containers-podman-intro]] == Introduction to Podman The Podman suite comprises three main tools and a number of supporting ones: * https://podman.io/[podman] is a daemonless container engine using docker-compatible commands * https://buildah.io/[buildah] generates OCI formatted container images * https://github.com/containers/skopeo[skopeo] works with remote OCI image registries [[containers-preparing]] == Preparing the System for Podman Containers [WARNING] ==== If running commands over SSH, or in a similar remote session, use man:screen[1], man:tmux[1], or similar to avoid losing the connection while restarting the firewall. ==== If ZFS is not available, switch to UFS storage and skip the ZFS commands below: [source,shell] ---- # sed -I .bak -e 's/driver = "zfs"/driver = "vfs"/' \ /usr/local/etc/containers/storage.conf ---- Otherwise, create the container storage dataset: [source,shell] ---- # zfs create -o mountpoint=/var/db/containers zroot/containers # zfs snapshot zroot/containers@empty ---- The File Descriptor filesystem is required: [source,shell] ---- # mount -t fdescfs fdesc /dev/fd ---- Podman uses FreeBSD's packet filter to forward container ports to the host network: [source,shell] ---- # test -c /dev/pf || kldload pf # sysctl net.pf.filter_local=1 ---- Amend `+/etc/sysctl.conf+` and `+/etc/fstab+` as appropriate, to make these changes permanent. [[containers-installing]] == Installing Podman Only the `+sysutils/podman-suite+` meta-package is required, but if the additional package:emulators/qemu-user-static[] package is installed, it becomes possible to build or test images for other architectures such as `+arm64+` on an `+amd64+` host. [source,shell] ---- # pkg install -r FreeBSD -y podman-suite emulators/qemu-user-static ---- Integrate changes from `+/usr/local/etc/containers/pf.conf.sample+` into `+/etc/pf.conf+`, setting egress macros appropriately, then restart the firewall: [source,shell] ---- # service pf restart ---- The packages install a number of template configuration files, none of which need to be edited immediately. Review and amend these as needed: [source,shell] ---- # pkg list buildah podman conmon \ ocijail containers-common \ containernetworking-plugins \ | grep /etc/ /usr/local/etc/containers/containers.conf.sample /usr/local/etc/containers/policy.json.sample /usr/local/etc/containers/registries.conf.sample /usr/local/etc/containers/storage.conf.sample /usr/local/etc/containers/pf.conf.sample ---- [[containers-terminal-tour]] == Importing and Running Containers [NOTE] ==== At present, all Podman containers on FreeBSD must run as root, as FreeBSD jails require this. ==== With the necessary tools and firewall rules in place, the officially published images can be fetched from https://download.freebsd.org/releases/OCI-IMAGES/[FreeBSD Releases], for https://download.freebsd.org/releases/OCI-IMAGES/{rel-latest}-RELEASE/aarch64/Latest/[aarch64] or https://download.freebsd.org/releases/OCI-IMAGES/{rel-latest}-RELEASE/amd64/Latest/[amd64] as appropriate. [[containers-importing]] === Importing FreeBSD OCI Images It is simplest to pull images directly from a public container registry, but for the strongest chain of trust, download them from https://download.freebsd.org/releases[FreeBSD.org] directly, and verify the checksums against the PGP-signed release announcement. [source,shell,subs="attributes"] ---- # export OCIBASE=https://download.freebsd.org/releases/OCI-IMAGES/{rel-latest}-RELEASE/amd64/Latest # podman load -i=$OCIBASE/FreeBSD-{rel-latest}-RELEASE-amd64-container-image-static.txz Getting image source signatures Copying blob 44defc6cee2e done | Copying config 5921c62e76 done | Writing manifest to image destination Loaded image: localhost/freebsd-static:{rel-latest}-RELEASE-amd64 # podman load -i=$OCIBASE/FreeBSD-{rel-latest}-RELEASE-amd64-container-image-dynamic.txz Getting image source signatures Copying blob 6054dffc3887 done | Copying config 33427d59f9 done | Writing manifest to image destination Loaded image: localhost/freebsd-dynamic:{rel-latest}-RELEASE-amd64 # podman load -i=$OCIBASE/FreeBSD-{rel-latest}-RELEASE-amd64-container-image-runtime.txz Getting image source signatures Copying blob dcbbfcb598fe done | Copying config 90c4936754 done | Writing manifest to image destination Loaded image: localhost/freebsd-runtime:{rel-latest}-RELEASE-amd64 # podman load -i=$OCIBASE/FreeBSD-{rel-latest}-RELEASE-amd64-container-image-notoolchain.txz Getting image source signatures Copying blob a16c94176cc3 done | Copying config 086572f35c done | Writing manifest to image destination Loaded image: localhost/freebsd-notoolchain:{rel-latest}-RELEASE-amd64 # podman load -i=$OCIBASE/FreeBSD-{rel-latest}-RELEASE-amd64-container-image-toolchain.txz Getting image source signatures Copying blob b04531b7d93d done | Copying config b927c11b2e done | Writing manifest to image destination Loaded image: localhost/freebsd-toolchain:{rel-latest}-RELEASE-amd64 ---- [[containers-listing]] === Listing Images [source,shell,subs="attributes"] ---- # podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/freebsd-toolchain {rel-latest}-RELEASE-amd64 b927c11b2e8d 13 days ago 660 MB localhost/freebsd-notoolchain {rel-latest}-RELEASE-amd64 086572f35cc9 13 days ago 152 MB localhost/freebsd-runtime {rel-latest}-RELEASE-amd64 90c493675429 13 days ago 34.1 MB localhost/freebsd-dynamic {rel-latest}-RELEASE-amd64 33427d59f990 13 days ago 14.5 MB localhost/freebsd-static {rel-latest}-RELEASE-amd64 5921c62e76c1 13 days ago 2.92 MB ---- Note that the image IDs are reproducible each time, and the `+IMAGE_ID+` column matches the hashes reported when importing the images. [[containers-listing-layers]] === Listing Layers It is possible to show the layers that comprise an image, demonstrating how the `+runtime+` image has three components, each one a layer in its own right: [source,shell] ---- # podman image tree ghcr.io/freebsd/freebsd-runtime:14.2 Image ID: c5f3e77557a9 Tags: [ghcr.io/freebsd/freebsd-runtime:14.2] Size: 35.07MB Image Layers ├── ID: cd53fb07fb66 Size: 5.449MB Top Layer of: [ghcr.io/freebsd/freebsd-static:14.2] ├── ID: a01d37f7777b Size: 10.4MB Top Layer of: [ghcr.io/freebsd/freebsd-dynamic:14.2] └── ID: 36b0c80ca1f7 Size: 19.21MB Top Layer of: [ghcr.io/freebsd/freebsd-runtime:14.2] ---- [[containers-public-registries]] === Using Public Registries While the most secure provenance is downloading from https://download.freebsd.org/releases[Official FreeBSD Releases], there are two public container registries managed by the FreeBSD Release and Cluster Admin teams. The images from both registries are identical, but provide a simpler and more container-friendly workflow. * https://hub.docker.com/u/freebsd[Docker Hub] * https://github.com/orgs/freebsd/packages[GitHub Container Registry] [[containers-fetching]] === Fetching Containers Images can be fetched from a public registry using `+podman pull+`: [source,shell,subs="attributes"] ---- # podman pull ghcr.io/freebsd/freebsd-notoolchain:{rel-latest} Trying to pull ghcr.io/freebsd/freebsd-notoolchain:{rel-latest}... Getting image source signatures Copying blob 711cf0d3c0ef done | Copying config 086572f35c done | Writing manifest to image destination 086572f35cc90b1a1d2b7904b63e8a849071b4ba89b15492f6da47a802372aa2 ---- [[containers-running]] === Running a Container Use `+podman run+` to start a container. The `+-it+` flags allocate an interactive terminal, and `+--rm+` removes the container when it exits. If no command is specified, the image's default entrypoint is used: [source,shell,subs="attributes"] ---- # podman run -it --rm ghcr.io/freebsd/freebsd-notoolchain:{rel-latest} # exit ---- A specific command can be given as well: [source,shell,subs="attributes"] ---- # podman run -it --rm ghcr.io/freebsd/freebsd-notoolchain:{rel-latest} uname -a FreeBSD c0038de70651 {rel-latest}-RELEASE FreeBSD {rel-latest}-RELEASE releng/{rel-latest}-n283562-96841ea08dcf GENERIC amd64 ---- As the container image does not include the kernel, man:freebsd-version[1] shows different results for the running kernel versus the installed userland. In this example, a {rel-latest-previous}-RELEASE container runs on a {rel-latest}-RELEASE host: [source,shell,subs="attributes"] ---- # podman run -it --rm ghcr.io/freebsd/freebsd-notoolchain:{rel-latest-previous} /bin/sh # freebsd-version -ru {rel-latest}-RELEASE {rel-latest-previous}-RELEASE # exit ---- [[containers-variations]] == Useful Variations and Tips Almost all of the `+podman run ...+` parameters also apply to `+podman build+`. Refer to the man:podman-run[1] and man:podman-build[1] manual pages for details. Use the `+--rm+` flag to have ephemeral containers clean themselves up afterwards. Use `+podman images -a+` to show all downloaded images: [source,shell,subs="attributes"] ---- # podman images -a REPOSITORY TAG IMAGE ID CREATED SIZE ghcr.io/freebsd/freebsd-runtime {rel-latest} 90c493675429 2 weeks ago 34.1 MB ---- Use `+podman ps -a+` to see running containers: [source,shell,subs="attributes"] ---- # podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES 3123623bef9b ghcr.io/freebsd/freebsd-runtime:{rel-latest} /bin/sh 4 minutes ago Up 4 minutes admiring_brattain ---- [[containers-env-vars]] === Environment Variables Podman sets a number of default environment variables in each container: [source,shell,subs="attributes"] ---- # podman run -it --rm ghcr.io/freebsd/freebsd-notoolchain:{rel-latest} /usr/bin/env container=podman TERM=xterm PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOME=/root HOSTNAME=60bae3343e6b ---- The `+HOSTNAME+` is set to the container ID by default. It can be overridden with `+--hostname+`, which is useful when the application inside the container needs a stable or meaningful hostname. Arbitrary environment variables can be passed in with `+--env+`: [source,shell,subs="attributes"] ---- # podman run --env FOO=BAR -it --rm ghcr.io/freebsd/freebsd-runtime:{rel-latest} # echo $FOO BAR ---- [[containers-volumes]] === Mounting Files and Volumes Both files and volumes can be passed into containers using `+--volume+`. For example, the `+runtime+` image does not contain man:which[1]: [source,shell,subs="attributes"] ---- # podman run -it --rm ghcr.io/freebsd/freebsd-runtime:{rel-latest} # which /bin/sh: which: not found ---- It can be mounted into the container from the host: [source,shell,subs="attributes"] ---- # podman run -it --rm --volume /usr/bin/which:/usr/bin/which \ ghcr.io/freebsd/freebsd-runtime:{rel-latest} # which which /usr/bin/which ---- For a lean image such as `+freebsd-static+`, mount the existing man:pkg-static[8] from the host to bootstrap man:pkg[8] inside the container. Sharing the host's package cache via `+--volume /var/cache/pkg+` avoids re-downloading packages that have already been fetched, which is particularly useful when building multiple containers. The `+--no-hosts+` flag prevents mounting `+/etc/hosts+`, which would otherwise interfere with package upgrades. [NOTE] ==== Sharing the package cache only works when the host and container run the same FreeBSD major version, as packages are version-specific. ==== [source,shell,subs="attributes"] ---- # podman run -it --rm \ --env ASSUME_ALWAYS_YES=true \ --no-hosts \ --volume /usr/local/sbin/pkg-static:/bin/pkg-static \ --volume /var/cache/pkg \ ghcr.io/freebsd/freebsd-static:{rel-latest} # pkg-static bootstrap -r FreeBSD Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:14:amd64/latest, please wait... Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done [fd343e182fa5] Installing pkg-2.1.2... [fd343e182fa5] Extracting pkg-2.1.2: 100% ---- Files and directories from the host can also be mounted into containers: [source,shell,subs="attributes"] ---- # podman run -it --rm \ --volume /etc/fstab:/etc/fstab \ --volume /tmp:/var/tmp \ --volume /tmp \ ghcr.io/freebsd/freebsd-runtime:{rel-latest} ---- [[containers-inspecting]] === Inspecting Image Contents To list all files in any image, including minimal images with no shell or tools, export the container filesystem and list its contents: [source,shell,subs="attributes"] ---- # podman export $(podman create --rm ghcr.io/freebsd/freebsd-static:{rel-latest} /) | tar tf - ---- The container images do not include man:pkg[8] itself, but man:pkg-static[8] can be mounted from the host to query the installed base system packages. Use `+pkg info -q+` to list package names, or `+pkg info -ql+` to show all files owned by packages: [source,shell,subs="attributes"] ---- # podman run --rm \ -v /usr/local/sbin/pkg-static:/pkg \ ghcr.io/freebsd/freebsd-runtime:{rel-latest} /pkg info -q FreeBSD-audit-lib-{rel-latest} FreeBSD-bzip2-lib-{rel-latest} FreeBSD-certctl-{rel-latest} FreeBSD-clibs-{rel-latest} FreeBSD-fetch-{rel-latest} FreeBSD-kerberos-lib-{rel-latest} FreeBSD-libarchive-{rel-latest} FreeBSD-libcasper-{rel-latest} FreeBSD-libexecinfo-{rel-latest} FreeBSD-libucl-{rel-latest} FreeBSD-mtree-{rel-latest} FreeBSD-ncurses-lib-{rel-latest} FreeBSD-openssl-{rel-latest} FreeBSD-openssl-lib-{rel-latest} FreeBSD-pam-lib-{rel-latest} FreeBSD-pkg-bootstrap-{rel-latest} FreeBSD-rc-{rel-latest} FreeBSD-runtime-{rel-latest} FreeBSD-xz-lib-{rel-latest} FreeBSD-zlib-{rel-latest} FreeBSD-zoneinfo-{rel-latest} FreeBSD-zstd-lib-{rel-latest} ---- When the host and container run different FreeBSD major versions, man:pkg[8] detects the ABI by inspecting `+/bin/sh+` inside the container, and will warn about the mismatch: [source,shell] ---- # podman run -it --rm \ --env ASSUME_ALWAYS_YES=true \ --no-hosts \ --volume /usr/local/sbin/pkg-static:/usr/sbin/pkg \ --volume /var/cache/pkg \ ghcr.io/freebsd/freebsd-runtime:14.4 /bin/sh # pkg bootstrap pkg: Warning: Major OS version upgrade detected. Running "pkg bootstrap -f" recommended ---- For images without `+/bin/sh+`, such as `+freebsd-dynamic+`, man:pkg-static[8] cannot detect the system ABI at all. [[containers-networking]] == Networking and Name Resolution By default, the Podman suite of tools will use man:mount_nullfs[8] to mount `+/etc/resolv.conf+` and a modified `+/etc/hosts+` from the jail host, as well as a `+.containerenv+` file in `+/var/run+`. This hosts file will conflict with base system package upgrades, so it is advised to skip this during `+podman build+` runs, but leave it enabled during production deployment: [source,shell] ---- # podman run --dns 1.2.3.4 ... # podman build --no-hosts ... ---- The `+--dns+` flag specifies a custom DNS server instead of mounting `+/etc/resolv.conf+` from the host. The `+--no-hosts+` flag prevents mounting `+/etc/hosts+` from the host. [[containers-building]] == Building Custom Images Custom images can be built directly from tarballs (for example those from man:poudriere[8], or official release tarballs), from existing tagged images, or bootstrapped from man:pkg[8]. [[containers-building-base]] === Building from Tarballs A custom image can be made from any FreeBSD root filesystem tarball using man:podman-import[1]. The tarball can be an official release `+base.txz+`, one produced by man:poudriere-image[8], or your own custom tarball. The final tagged image can be pushed to registries, modified, and used for further image creation. [source,shell,subs="attributes"] ---- # podman import --os freebsd \ --arch amd64 \ --message 'Import FreeBSD {rel-latest}-RELEASE base.txz' \ https://download.freebsd.org/releases/amd64/{rel-latest}-RELEASE/base.txz Downloading from "https://download.freebsd.org/releases/amd64/{rel-latest}-RELEASE/base.txz" Getting image source signatures Copying blob 3768988b151c done | Copying config 332bec83a4 done | Writing manifest to image destination sha256:332bec83a428efa6c9f7d1f8b3fbd589c5613d938dca7da5125240c89f4f3dcd # podman image tag 332bec83a428 localhost/freebsd-base:{rel-latest} # podman image ls REPOSITORY TAG IMAGE ID CREATED SIZE localhost/freebsd-base {rel-latest} 332bec83a428 5 minutes ago 715 MB ---- [[containers-building-containerfile]] === Building from Containerfiles Images can be built using a `+Containerfile+`, similar to a Dockerfile. In most cases, the `+freebsd-notoolchain+` image is the most convenient base, as it includes nearly all standard system tools. For leaner containers, start from `+freebsd-static+`, `+freebsd-dynamic+`, or `+freebsd-runtime+` as appropriate, and add only what is needed: [source,dockerfile,subs="attributes"] ---- # Containerfile FROM ghcr.io/freebsd/freebsd-notoolchain:{rel-latest} RUN env ASSUME_ALWAYS_YES=yes IGNORE_OS_VERSION=yes pkg bootstrap -r FreeBSD RUN pkg update RUN pkg upgrade -y RUN pkg clean -y ENTRYPOINT /bin/sh ---- Build the image with man:podman-build[1]: [source,shell,subs="attributes"] ---- # podman build --no-hosts --squash \ -t localhost/freebsd-base:{rel-latest} \ -f ./Containerfile ---- Further images can be layered on top: [source,dockerfile,subs="attributes"] ---- # Containerfile.webserver FROM localhost/freebsd-base:{rel-latest} RUN pkg install -y lang/python3 RUN pkg clean -y ENTRYPOINT /usr/local/bin/python3 -m http.server ---- [source,shell,subs="attributes"] ---- # podman build --no-hosts \ -t localhost/python-www:{rel-latest} \ -f ./Containerfile.webserver ---- Run the web server in the background with `+--detach+`, and use `+-p+` to map a host port to the container port. In this example, the container listens on its default port 8000, which is mapped to port 8888 on the host: [source,shell,subs="attributes"] ---- # c=$(podman run --detach --rm -p 8888:8000 localhost/python-www:{rel-latest}) ---- The port mapping uses man:pf[4] redirect rules. These rules redirect traffic arriving over the network, so the mapped port must be accessed from another host, or via the host's network-facing IP address: [source,shell] ---- $ fetch -v http://172.16.2.10:8888/ resolving server address: 172.16.2.10:8888 requesting http://172.16.2.10:8888/ remote size / mtime: 784 / 0 fetch.out 784 B 3791 kBps 00s ---- To access the container directly from the host, use the container's own IP on its listening port: [source,shell] ---- # podman inspect -f '{{.NetworkSettings.IPAddress}}' $c 10.88.0.91 # fetch -v http://10.88.0.91:8000/ resolving server address: 10.88.0.91:8000 requesting http://10.88.0.91:8000/ remote size / mtime: 784 / 0 fetch.out 784 B 25 MBps 00s ---- [NOTE] ==== Port mappings via `+-p+` are handled by man:pf[4] redirect rules and only apply to traffic arriving over the network. Traffic originating from the jail host itself to `+localhost+` or `+127.0.0.1+` will not be redirected. From the host, use the container's IP address directly instead. ==== [[containers-advanced]] == Advanced Usage [[containers-daemonising]] === Daemonising Podman FreeBSD's Podman implementation provides two man:rc[8] services: * The `+podman+` service runs at boot and ensures that all containers marked with `+restart-policy=always+` are started. * The `+podman_service+` service runs the https://docs.podman.io/en/latest/_static/api.html[Podman API service], providing a REST API and listening on `+/var/run/podman/podman.sock+` by default. Enable them as follows: [source,shell] ---- # sysrc podman_enable=YES # sysrc podman_service_enable=YES # sysrc podman_service_flags='--time 0' # service podman start # service podman_service start ---- Containers that should restart automatically after a host reboot must be run with the `+--restart=always+` option: [source,shell] ---- # podman run --detach --restart=always my-image ---- [[containers-linux]] === Running Linux Containers It is possible to run many Linux container images using FreeBSD's Linux emulation: [source,shell] ---- # service linux onestart # podman run --rm --os=linux docker.io/alpine cat /etc/os-release | head -1 Trying to pull docker.io/library/alpine:latest... Getting image source signatures Copying blob 4abcf2066143 done | Copying config 05455a0888 done | Writing manifest to image destination NAME="Alpine Linux" ---- [NOTE] ==== Linux containers that depend on systemd, expect to be PID 1, or rely on Linux-specific kernel interfaces may not work correctly under FreeBSD's Linux emulation. ==== [[containers-local-registry]] === Running a Local Registry A registry is a web server for storing and sharing OCI images. The https://freshports.org/sysutils/docker-registry[sysutils/docker-registry] port provides a simple registry suitable for local development or a small organisation. https://zotregistry.dev/[Zot Registry] is a more comprehensive modern alternative. [source,shell] ---- # pkg install -r FreeBSD sysutils/docker-registry # zfs create zroot/var/db/registry # chown -R www:www /var/db/registry # sysrc docker_registry_enable=YES # sysrc docker_registry_user=www # sed -i '' -E -e 's,rootdirectory:.+,rootdirectory: /var/db/registry,' \ /usr/local/etc/docker-registry/config.yml # touch /usr/local/etc/docker-registry/htpasswd # chown -R root:www /usr/local/etc/docker-registry/config.yml \ /usr/local/etc/docker-registry/htpasswd # chmod 0640 /usr/local/etc/docker-registry/config.yml \ /usr/local/etc/docker-registry/htpasswd ---- A sample configuration for `+/usr/local/etc/docker-registry/config.yml+`: [source,yaml] ---- version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/db/registry http: addr: :5000 secret: headers: X-Content-Type-Options: [nosniff] auth: htpasswd: realm: basic-realm path: /usr/local/etc/docker-registry/htpasswd health: storagedriver: enabled: true interval: 10s threshold: 3 ---- Start the registry and verify it is running: [source,shell] ---- # service registry start # curl -u admin:passwd http://localhost:5000/v2/ ---- [TIP] ==== It is recommended to serve the registry over TLS, behind a reverse proxy such as nginx or haproxy. ==== [[containers-syncing]] === Synchronising Registries It is possible to synchronise official FreeBSD images into a local registry using `+skopeo+`. The following example replicates all FreeBSD-related images from https://hub.docker.com/u/freebsd[Docker Hub] to a local registry: [source,yaml] ---- # sync.yml docker.io: images: freebsd/freebsd-static: [] freebsd/freebsd-dynamic: [] freebsd/freebsd-runtime: [] ---- [source,shell] ---- $ skopeo sync --src yaml --dest docker --all sync.yml cr.example.net/freebsd INFO[0000] Processing repo repo=freebsd/freebsd-static INFO[0000] Querying registry for image tags repo=freebsd/freebsd-static ... INFO[0771] Synced 42 images from 3 sources ---- So long as the credentials in `+/root/.config/containers/auth.json+` are up to date, root access is not required to sync images. [[containers-registries-auth]] === Working with Container Registries Registries generally require authentication for push operations, and optionally for pull. Credentials are saved in `+/root/.config/containers/auth.json+` by default after login: [source,shell] ---- # podman login ghcr.io -u username Password: Login Succeeded! ---- Images can then be pushed to a registry: [source,shell,subs="attributes"] ---- # podman push localhost/freebsd-runtime:{rel-latest} \ docker://ghcr.io/example/freebsd-runtime:{rel-latest} Getting image source signatures Copying blob bbacfdfbe140 done | Copying config 786f2592a8 done | Writing manifest to image destination ---- Public images can be pulled without authentication: [source,shell,subs="attributes"] ---- # podman pull ghcr.io/freebsd/freebsd-runtime:{rel-latest} ---- [[containers-building-sources]] == Building Container Images from Sources The FreeBSD release tooling provides an `+oci-release+` target to build the necessary images for `+podman load+` to use. It requires building world, kernel, and base system packages first, so this can take a while. The following example builds `+arm64+` images: [source,shell] ---- # cd /usr/src \ && make TARGET_ARCH=aarch64 TARGET=arm64 -s -j32 buildworld \ && make TARGET_ARCH=aarch64 TARGET=arm64 KERNCONF=GENERIC -s -j32 buildkernel \ && make TARGET_ARCH=aarch64 TARGET=arm64 KERNCONF=GENERIC -s -j32 packages \ && cd ./release \ && make TARGET_ARCH=aarch64 TARGET=arm64 -j32 -s clean \ && make KERNCONF=GENERIC TARGET_ARCH=aarch64 TARGET=arm64 WITH_OCIIMAGES=yes \ -s oci-release ---- And similarly for `+amd64+`: [source,shell] ---- # cd /usr/src \ && make TARGET_ARCH=amd64 TARGET=amd64 -s -j32 buildworld \ && make TARGET_ARCH=amd64 TARGET=amd64 KERNCONF=GENERIC -s -j32 buildkernel \ && make TARGET_ARCH=amd64 TARGET=amd64 KERNCONF=GENERIC -s -j32 packages \ && cd ./release \ && make TARGET_ARCH=amd64 TARGET=amd64 -s -j32 clean \ && make KERNCONF=GENERIC TARGET_ARCH=amd64 TARGET=amd64 \ WITH_OCIIMAGES=yes -s oci-release ---- [[containers-cross-arch]] == Cross-Architecture Testing The `+emulators/qemu-user-static+` package allows testing container images built for other architectures. After installing the package, enable and start the service to register image activators for all emulated architectures: [source,shell] ---- # pkg install emulators/qemu-user-static # service qemu_user_static enable # service qemu_user_static start ---- Then run an `+arm64+` image on an `+amd64+` host by mounting the appropriate QEMU binary: [source,shell] ---- # podman run -it --rm --arch=arm64 \ -v /usr/local/bin/qemu-aarch64-static:/usr/local/bin/qemu-aarch64-static \ ghcr.io/freebsd/freebsd-runtime:14.snap uname -a FreeBSD 73d4049d10b2 14.2-RELEASE-p1 FreeBSD 14.2-RELEASE-p1 GENERIC arm64 ---- [[containers-troubleshooting]] == Troubleshooting [[containers-troubleshooting-hosts]] === Package Upgrades and Mounted Files Podman mounts `+/etc/resolv.conf+` and `+/etc/hosts+` into containers using man:mount_nullfs[8]. These mounts can cause errors during man:pkg[8] operations with messages such as `+Cross-device link+`: [source] ---- pkg: Fail to rename /etc/.pkgtemp.hosts.VeIDrHM0sKN5 -> /etc/hosts:Cross-device link ---- To avoid this, use `+--no-hosts+` and `+--dns+` flags: [source,shell,subs="attributes"] ---- # podman run --no-hosts --dns 1.1.1.1 -it --rm \ ghcr.io/freebsd/freebsd-runtime:{rel-latest} /bin/sh ---- [[containers-troubleshooting-networking]] === Checking Networking Start with the firewall rules from `+/usr/local/etc/containers/pf.conf.sample+`. Test connectivity step by step from within a container: [source,shell,subs="attributes"] ---- # podman run --no-hosts --dns 1.1.1.1 \ --env ASSUME_ALWAYS_YES=1 \ -it --rm \ ghcr.io/freebsd/freebsd-runtime:{rel-latest} \ /bin/sh # route show 1.1.1.1 route to: 1.1.1.1 destination: default gateway: 10.88.0.1 interface: eth0 # ping -c 3 10.88.0.1 PING 10.88.0.1 (10.88.0.1): 56 data bytes 64 bytes from 10.88.0.1: icmp_seq=0 ttl=64 time=0.083 ms ... # ping -c 3 1.1.1.1 PING 1.1.1.1 (1.1.1.1): 56 data bytes 64 bytes from 1.1.1.1: icmp_seq=0 ttl=60 time=0.920 ms ... # fetch -v http://1.1.1.1/ ... # pkg -dd bootstrap -r FreeBSD ---- If man:ping[8] fails, check the firewall rules for blocked ICMP. If man:fetch[1] fails, check the firewall rules for blocked TCP on ports 80 and 443. If man:pkg[8] fails but ICMP and TCP work, this may be a fragmentation or MTU problem. Add `+set reassemble yes no-df+` to `+/etc/pf.conf+` and restart the firewall. For debugging blocked packets, enable `+log+` on all block rules in `+/etc/pf.conf+` and use man:tcpdump[1] on the man:pflog[4] device: [source,shell] ---- # service pflog onerestart # tcpdump -vvveni pflog0 icmp or net 10.88.0.0/16 ---- [[containers-troubleshooting-mtu]] === MTU Consistency Ensure MTU values are consistent across the primary network interface, the container bridge, and the container itself. Mismatched MTU values can cause packet fragmentation and connectivity failures. In the following example, `+vtnet0+` has MTU 9000, but the bridge and containers have MTU 1500. In general, align the internal layout to match the external network: [source,shell] ---- # ifconfig vtnet0 mtu 9000 # ifconfig cni-podman0 mtu 9000 ---- Inside the container: [source,shell] ---- # ifconfig eth0 mtu 9000 ---- The bridges and epairs used by Podman are ephemeral and will need to be configured for each bridge creation and each container. In some cloud environments, adding `+set reassemble yes no-df+` to `+/etc/pf.conf+` may also be required. diff --git a/shared/contrib-386bsd.adoc b/shared/contrib-386bsd.adoc index a8e239de0e..6b2bb9996d 100644 --- a/shared/contrib-386bsd.adoc +++ b/shared/contrib-386bsd.adoc @@ -1,95 +1,95 @@ * Adam Glass * Adrian Hall * Andrey A. Chernov * Andrew Gerweck * Andrew Herbert * Andrew Moore * Andy Valencia * Arne Henrik Juul * Bakul Shah * Barry Irwin * Barry Lustig * Bob Wilcox * Branko Lankester * Brett Lymn * Charles Hannum * Chris G. Demetriou * Chris Torek * Christoph Robitschko * Daniel Poirot * Dave Burgess * Dave Rivers * David Dawes * David Greenman * Eric J. Haug * Felix Gaehtgens * Frank Maclachlan * Gary A. Browning * Gary Howland * Geoff Rehmet * Goran Hammarback * Guido van Rooij * Guy Antony Halse * Guy Harris * Havard Eidnes * Herb Peyerl * Holger Veit * Ishii Masahiro, R. Kym Horsell * J.T. Conklin * Jagane D Sundar * James Clark * James Jegers * James W. Dolter * James da Silva et al * Jay Fenlason * Jim Wilson * Jörg Lohse * Jörg Wunsch * John Dyson * John Woods * Jordan K. Hubbard * Julian Elischer * Karl Dietz * Karl Lehenbauer * Keith Bostic * Ken Hughes * Kent Talarico -* Kevin Lahey +* Kevin Lahey * Konstantinos Konstantinidis * Marc Frajola * Mark Tinguely * Martin Renters * Michael Clay * Michael Galassi * Mike Durkin * Naoki Hamada * Nate Williams * Nick Handel * Pace Willisson * Paul Kranenburg * Paul Mackerras * Paul Popelka * Peter da Silva * Phil Sutherland * Poul-Henning Kamp * Ralf Friedl * Rick Macklem * Robert D. Thrush * Rodney W. Grimes * Sascha Wildner * Scott Burris * Scott Reynolds * Seamus Venasse * Sean Eric Fagan * Sean McGovern * Simon J Gerraty * Stephen McKay * Terry Lambert * Terry Lee * Tor Egge * Warren Toomey * Wiljo Heinen * William Jolitz * Wolfgang Solfrank * Wolfgang Stanglmeier * Yuval Yarom diff --git a/shared/contrib-additional.adoc b/shared/contrib-additional.adoc index c1a2adba20..3696dc6e8a 100644 --- a/shared/contrib-additional.adoc +++ b/shared/contrib-additional.adoc @@ -1,2414 +1,2414 @@ * ABURAYA Ryushirou * AIDA Shinra * AMAGAI Yoshiji * Aaron Bornstein * Aaron Myles Landwehr * Aaron Smith * Aaron Straup Cope * Aaron Voisine * Aaron Zauner * Aasmund Eikli * Achim Patzner * Ada T Lim * Adam Baran * Adam C. Migus * Adam Glass * Adam Herzog * Adam Jette * Adam Kranzel * Adam McDougall * Adam McLaurin * Adam Strohl * Adam Wight * Adoal Xu * Adrian Colley * Adrian Filipi-Martin * Adrian Hall * Adrian Mariano * Adrian Pircalabu * Adrian Steinmann * Adrian T. Filipi-Martin * Aftab Jahan Subedar * Ajit Thyagarajan * Akinori YAMADA * Akira Ikeuchi * Akira SAWADA * Akira Watanabe * Akito Fujita * Akos Somfai * Al Hoang * Alain Kalker * Alan Amesbury * Alan Bawden * Alan Snelson * Alastair Hogge * Alban Maire * Albert Graef * Aldert Nooitgedagt * Aldis Berjoza * Alec Wolman * Aled Morris * Aleksander Fafula * Aleksandr A Babaylov * Aleksandr S. Goncharov * Alessandro Sagratini * Alex D. Chen * Alex Deiter * Alex G. Bulushev * Alex Kapranoff * Alex Keda * Alex Kiesel * Alex Le Heux * Alex M * Alex Miller * Alex Nunes Soares * Alex Perel * Alex Pesternikov * Alex Rodioukov * Alex Rousskov * Alex Semenyaka * Alex Steiner * Alex Trull * Alex Varju * Alex Vasylenko * Alex Wilkinson * Alex Zepeda * Alexander Bechikov * {arundel} * Alexander Churanov * Alexander B. Povolotsky * Alexander Gelfenbain * Alexander Pereira Girald * Alexander Grigoryev * Alexander Gromnizki * Alexander Haderer * Alexander Koch * Alexander Kojevnikov * Alexander Kovalenko * Alexander Moisseev * Alexander Novitsky * Alexander Nusov * Alexander Peresunko * Alexander Pohoyda * Alexander Pyhalov * alexander smishlajev * Alexander V. Ribchansky * Alexander Yerenkow * Alexander Sieg * Alexander Zagrebin * Alexander Zhuravlev * Alexandre Liberato * Alexandre Peixoto * Alexandre Snarskii * Alexandre Vasconcelos * Alexandros Kosiaris * Alexandru Ciobanu * Alexey Bobkov * Alexey Illarionov * Alexey V. Antipovsky * Alexey V. Degtyarev * Alexey V. Neyman * Alexey Y. Mikhailov * Alexey Shuvaev * Alexey Zaytsev * Alexis Yushin * Ali Mashtizadeh * Alistair G. Crooks * Allan Bowhill * Allan Saddi * Allen Campbell * Alphons "Fonz" van Werven * Amakawa Shuhei * Amar Takhar * Amaziles José Antonio Martins de Carvalho * Amir Farah * Amir Shalem * Amarendra Godbole * Amy Baron * Anthony Garcia * Anatoliy Dmytriyev * Anatoly A. Orehovsky * Anatoly Borodin * Anatoly Vorobey * Anatoly Zherdev * Anders Andersson * Anders Nor Berle * Anders Thulin * Anders Troback * Anderson Aguiar * Anderson S. Ferreira * Andi Payn * Andre Albsmeier * André Franciosi * Andre Goeree * Andre Yelistratov * Andrea Venturoli * Andreas Andersson * Andreas Berg * Andreas Bilke * Andreas Fehlner * Andreas Fuchs * Andreas Gustafsson * Andreas Haakh * Andreas Heil * Andreas K Foerster * Andreas Karlsson * Andreas Kasparz * Andreas Kohn * Andreas Kohout * Andreas Lohr * Andreas Möller * Andreas Riedel * Andreas Sommer * Andreas Wetzel * Andreas Wrede * Andrei V. Shetuhin * Andrej Ebert * Andres Vega Garcia * Andrew Arensburger * Andrew Atrens * Andrew Boothman * Andrew Gillham * Andrew Gordon * Andrew Greenwood * Andrew Herbert * Andrew J. Caines * Andrew J. Korty * Andrew Khlebutin * Andrew Kochetkov * Andrew Kolchoogin * Andrew L. Kilpatrick * Andrew L. Neporada * Andrew Marks * Andrew McKay * Andrew McNaughton * Andrew McRae * Andrew Morton * Andrew P. Lentvorski * Andrew Predoehl * Andrew Reilly * Andrew Romanenko * Andrew S. Midthune * Andrew Shevtsov * Andrew Stevenson * Andrew Timonin * Andrew V. Stesin * Andrew V. Stikheev * Andrew Webster * Andrey Cherkashin * Andrey Fesenko * Andrey Novikov * Andrey Simonenko * Andrey Surkov * Andrey Sverdlichenko * Andrey Tchoritch * Andris Raugulis * Andy Farkas * Andy Fawcett * Andy Gilligan * Andy Kosela * Andy Miller * Andy Newman * Andy Pavlo * Andy Sparrow * Andy Valencia * Andy Whitcroft * Anes Muhametov * Angel Todorov * Angelo Turetta * Anish Mistry * Anthony C. Chavez * Anthony Ginepro * Anthony Mawer * Anthony Yee-Hang Chan * Antoine Beaupre * Antoine Pelisse * Anton Hryciuk * Anton N. Bruesov * Anton Shterenlikht * Anton Tornqvist * Anton Voronin * Anton Yuzhaninov * Antonio Bonifati * Antonio Carlos Venancio Junior * Antti Kaipila * Aragon Gouveia * Are Bryne * Ari Suutari * Arindum Mukerji * Arjan de Vet * Arnaud Berthomier * Arnaud Launay * Arne Henrik Juul * Aron Schlesinger * Aron Stansvik * Artem Kazakov * Artem Naluzhnyy * Artem Nosov * Ashley Penney * Ask Bjoern Hansen * Athanasios Douitsis * Atsushi Furuta * Atsushi Murai * Attila Nagy * Atushi Sakauchi * Autrijus Tang * Axel Gonzalez * Azrael JD * Balázs Nagy * Barry Bierbauch * Barry Lustig * Bartosz Fabianowski * Bayanzul Lodoysamba * Ben Hutchinson * Ben Jackson * Ben Walter * Ben Woolley * Benedikt Köhler * Beni Keller * Benjamin Lewis * Benjamin Lutz * Bennett Wetters * Benny Kjrgaard * Benoit Calvez * Berend de Boer * Bernd Luevelsmeyer * Bernd Rosauer * Bill Cadwallader * Bill Kish * Bill Lloyd * Bill Moran * Bill Trost * Björn König * Björn Lindström * Blaz Zupan * BluePex Security Solutions * Bob Eager * Bob Frazier * Bob Van Valzah * Bob Willcox * Boris Kovalenko * Boris Lytochkin * Boris Staeblow * Boyd R. Faulkner * Brad Chapman * Brad Hendrickse * Brad Jones * Brad Karp * Brad Lanam * Bradley Dunn * Bram Moolenaar * Brandon Fosdick * Brandon Gillespie * Brent B. Powers * Brent J. Nordquist * Brett Lymn * Brett Taylor * Brian Campbell * Brian Cully * Brian Gardner * Brian Handy * Brian Litzinger * Brian M. Clapper * Brian McGovern * Brian Moore * Brian R. Gaeke * Brian R. Haug * Brian Skrab * Brian Tao * Brion Moss * Bruce Albrecht * Bruce Gingery * Bruce J. Keeler * Bruce Murphy * Bruce Walter * Bruno Schwander * Byung-Hee HWANG * Camson Huynh * Carey Jones * Carl Fongheiser * Carl Makin * Carl Mascott * Carl Schmidt * Carlos A. M. dos Santos * Carlos Eduardo G. Carvalho * Carsten Larsen * Casper * Castor Fu * Cédric Lamalle * Cezary Morga * Chad Castleberry * Chad Jacob Milios * Chain Lee * Charles Hannum * Charles Henrich * Charles Mott * Charles Owens * Charles Swiger * Cheng-Tao Lin * ChenGuang LI * Chess Griffin * Chet Ramey * Chi-Feng QU * Chia-Hsing Yu * Chia-liang Kao * Chiang Cheng-Hsiung * Chie Taguchi * Chih-Hsin Chang * Chiharu Shibata * Chip Norkus * Choe, Cheng-Dae * Chris Burkert * Chris Csanady * Chris Dabrowski * Chris Dillon * Chris Hutchinson * Chris Howells * Chris Jones * Chris Knight * Chris Larsen * Chris Laverdure * Chris Moerz * Chris Pepper * Chris Pressey * Chris Shenton * Chris Stenton * Chris Torek * Christian Geier * Christian Gusenbauer * Christian Haury * Christian Heckendorf * Christian Lackas * Christian Laursen * Christian Schade * Christian Ullrich * Christian Zander * {kuku} * Christoph Robitschko * Christoph Weber-Fahr * Christophe Juniet * Christopher Boumenot * Christopher G. Demetriou * Christopher Hall * Christopher Illies * Christopher J. Ruwe * Christopher K. Davis * Christopher Key * Christopher Knaust * Christopher N. Harrell * Christopher Nehren * Christopher Preston * Christopher T. Johnson * Christopher Vance * Chrisy Luke * Chuck Hein * Clayton Eduardo dos Santos * Clayton Rollins * Clement MOULIN * Cliff Rowley * clutton * Clive Crous * Colin Booth * Colman Reilly * Conor McDermottroe * Conrad Sabatier * Constantin S. Svintsoff * Coranth Gryphon * Corey Halpin * Corey Smith * Cornelis van der Laan * Cosmin Stroe * Cove Schneider * Craig Boston * Craig Butler * Craig Loomis * Craig Metz * Craig Spannring * Craig Struble * Cristian Ferretti * Cristiano Rolim Pereira * Curt Mayer * Cyril Guibourg * Cyrille Lefevre * Cyrus Rahman * Daan Vreeken * Dai Ishijima * Daisuke Aoyama * Daisuke Watanabe * Damian Gerow * Damian Hamill * Damien Tougas * Dan Angelescu * Dan Caescu * Dan Cross * Dan Lukes * Dan Nelson * Dan Papasian * Dan Pelleg * Dan Piponi * Dan Rench * Dan Smith * Dan Walters * Daniel Austin * Daniel B. Hemmerich * Daniel Blankensteiner * Daniel Bretoi * Daniel Bryan * Daniel Hagan * Daniel Levai * Daniel J. O'Connor * Daniel Morante * Daniel O'Connor * Daniel Poirot * Daniel Rock * Daniel Roethlisberger * Daniel Tihanyi * Daniel W. McRobb * Daniel W. Steinbrook * Daniel Wijnands * Daniel Ylitalo * Danny Braniss * Danny Egen * Danny Howard * Danny J. Zerkel * Danny Pansters * Dario Freni * Darren Pilgrim * Dave Adkins * Dave Andersen * Dave Blizzard * Dave Bodenstab * Dave Burgess * Dave Chapeskie * Dave Cornejo * Dave Edmondson * Dave Glowacki * Dave Green * Dave Marquardt * {tweten} * David A. Adkins * David A. Bader * David Borman * David Bremner * David Bushong * David Chaplin-Loebell * Davide D'Amico * David Dawes * David Demelier * David Filo * David G. Holm * David Gardner * David Gilbert * David H. Munro * David Holland * David Holloway * David Horwitt * David Hovemeyer * David Johnson * David Jones * David Julien * David K. Gerry * David Kalliecharan * David Kelly * David Kirchner * David Kulp * David L. Nugent * David Landgren * David Lay * David Le Brun * David Leonard * David Magda * David Muir Sharnoff * David O'Rourke * David Otto * David Quattlebaum * David Romano * David S. Miller * David Shane Holden * David Siebörger * David Sugar * David Syphers * David Sze * David Terry * David Vachulka * David Wolfskill * David Yeske * Dax Labrador * Dean Gaudet * Dean Hollister * Dean Huxley * Demetris Procopiou * Denis Barov * Denis Fortin * Denis Generalov * Denis Philippov * Denis E. Podolskiy * Denis Pokataev * Denis Shaposhnikov * Dennis Cabooter * Dennis Glatting * Dennis S. Davidoff * Denton Gentry * Derek E. Schrock * Derek Inksetter * Derik van Zuetphen * Dermot Tynan * Dhananjay Balan * Diego Depaoli * Dikshie * Dikshie * Dierk Sacher * Dirk Engling * Dirk Gouders * Dirk Jagdmann * Dirk Keunecke * Dirk Nehrling * Dirk-Willem van Gulik * Ditesh Shashikant Gathani * Dmitri Nikulin * Dmitriy Limonov * Dmitry A. Yanko * Dmitry Afanasiev * Dmitry Dyomin * Dmitry Karasik * Dmitry Kazarov * Dmitry Khrustalev * Dmitry Kohmanyuk * Dmitry Pryadko * Dmitry Semkin * Dmitry V. Sukhodoyev * Dmitry Wagin * Dmytro Rud * Dom Mitchell * Domas Mituzas * Dominic Marks * Dominic Mitchell * Dominik Brettnacher * Dominik Rothert * Dominique Goncalves * Don Croyle * Don Morrison * Don Owens * {whiteside} * Don Yuniskis * Donald Maddox * Donn Miller * Doug Harple * Doug Penner * Douglas A. Maske * Douglas Carmichael * Douglas Crosher * Douglas K. Rand * Douglas W. Thrift * Drew Derbyshire * Dustin Sallings * Dylan Carlson * Dylan Simon * ELISA Font Project * Eckart "Isegrim" Hofmann * Ed Gold * Ed Hudson * Ederson de Moura * Edgardo Garcia Hoeffler * Edmondas Girkantas * Eduard Martinescu * Edward Chuang * Edward Sanford Sutton, III * Edward Wang * Edwin Mons * Eero Hänninen * Ege Rekk * Eiji-usagi-MATSUmoto * Eijiro Shibusawa * Eike Bernhardt * Eintisy Chuang * Eliane Vidal * Elias Mandouvalos * Elisey Savateev * Elmar Bartel * Emily Boyd * Eoin Lawless * Eric A. Griff * Eric Anderson * Eric Blood * Eric Camachat * Eric Cronin * Eric D. Futch * Eric F. Crist * Eric Freeman * Eric J. Haug * Eric J. Schwertfeger * Eric Kjeldergaard * Eric L. Hernes * Eric Masson * Eric Ogren * Eric P. Scott * Eric Schnoebelen * Eric Shao-yu Cheng * Eric Sprinkle * Eric W. Bates * Eric Yu * Erich Stefan Boleyn * Erich Zigler * Erik E. Rantapaa * Erik Greenwald * Erik H. Bakke * Erik H. Moe * Erik L. Chen * Ernie Smallis * Ernst Winter (http://berklix.org/ewinter/[Deceased]) * Espen Skoglund * Espen Tagestad * Eugene M. Kim * Eugene Ossintsev * Eugene Radchenko * Eugene Ray * Eugene Zheganin * Eugeney Ryzhyk * Eugeny Kuzakov * Evan Champion * Evan Sarmiento * Evgueni V. Gavrilov * Ewgenij Gawrilow * FUJIMOTO Kensaku * FURUSAWA Kazuhisa * Fabian Freyer * Fabian Keil * Fabian M. Borschel * Fabiano Sidler * Fabien Devaux * Fabio Tosques * Fabrice Aneche * Fangrui Song * Fanying Jen * Faried Nawaz * Fernan Aguero * Ferruccio Vitale * Filipe Rocha * Filippo Natali * Flemming Jacobsen * Florian Unglaub * Fong-Ching Liaw * Francis M J Hsieh * Francisco Cabrita * Francisco Gomez * Francisco Reyes * Franco Corbelli * François Tamone * Frank Bartels * Frank Behrens * Frank Börner * Frank Chen Hsiung Chan * Frank Denis * Frank Gründer * Frank MacLachlan * Frank Mayhar * Frank Nobis * Frank Ruell * Frank Steinborn * Frank Volf * Frank Wall * Frank W. Josellis * Frank ten Wolde * Frank van der Linden * Franz Klammer * Fraser Tweedale * Fred Cawthorne * Fred Gilham * Fred Templin * Freddie Cash * Frederic Dubuy * Frédéric Praca * Frederick Earl Gray * Fredrik Lennmark * Fredrik Lindberg * Frerich Raabe * Fumihiko Kimura * Fuyuhiko Maruyama * {stanislav} * Gábor Kincses * Gábor Zahemszky * Gasol Wu * Gabriel Rizzo * Gareth McCaughan * Garrett Rooney * Gary A. Browning * Gary Hayers * Gary Howland * Gary J. * Gary Kline * Gaspar Chilingarov * Gautam Mani * Gavin McDonald * Gavin Mu * Gea-Suan Lin * Geoff Glasson * Geoff Rehmet * Geoffrey Mainland * Geoffroy Rivat * Georg Graf * Georg Wagner * George Hartzell * George Liaskos * Gerasimos Dimitriadis * Geraud Continsouzas * Gerhard Gonter * Gerrit Beine * Giacomo Mariani * Gianlorenzo Masini * Gianmarco Giovannelli * Gil Kloepfer Jr. * Gilad Rom * Gilbert Morgan * Giles Lean * Ginga Kawaguti * Gleb Sushko * Glen Foster * Giel van Schijndel * Glenn Johnson * Godmar Back * Goran Hammarback * Goran Mekić * Gord Matzigkeit * Gordon Greeff * Graham Wheeler * Greg A. Woods * Greg Albrecht * Greg Ansley * Greg Becker * Greg Fitzgerald * Greg J. * Greg Kennedy * Greg Robinson * Greg Troxel * Greg Ungerer * Gregory Bond * Gregory D. Moncreaff * Grün Christian-Rolf * Guillaume Paquet * Gurkan Sengun * Gustau Pérez * Gustavo Fukao * Guy Brand * Guy Coleman * Guy Harris * Guy Poizat * Guy Tabrar * H. Wade Minter * HAMADA Naoki * HATANOU Tomomi * HIYAMA Takeshi * HONDA Yasuhiro * HOSOBUCHI Noriyuki * HOTARU-YA * Haesu Jeon * Hakisho Nukama * Hammurabi Mendes * Hannes Frederic Sowa * Hannu Savolainen * Hans Huebner * Hans Petter Bieker * Hans Zuidam * Hans-Christian Ebke * Hansjoerg Pehofer * Harald Schmalzbauer * Harald Wille * Hardy Schumacher * Harlan Stenn * Harold Barker * Harry Coin * Harry Newton * Havard Eidnes * Heath Nielson * Heikki Suonsivu * Heiko W. Rupp * Heiner Eichmann * Heiner Strauss * Helko Glathe * Helmut F. Wirth * Hendrik Scholz * Henning Matyschok * Henri Michelon * Henrik Brautaset Aronsen * Henrik Friedrichsen * Henrik Holst * Henrik Motakef * Henrik Nymann Jensen * Henrik Vestergaard Draboel * Henry Hu * Henry Whincup * Herb Peyerl * Herbert J. Skuhra * Hernan Di Pietro * Hideaki Machida * Hideaki Ohmon * Hidekazu Kuroki * Hideki Yamamoto * Hideyuki Suzuki * Hirayama Issei * Hiroaki Sakai * Hiroharu Tamaru * Hirohisa Yamaguchi * Hironori Ikura * Hiroshi Nishikawa * Hiroto Kagotani * Hiroya Tsubakimoto * Holger Lamm * Holger Veit * Holm Tiffe * Horance Chou * Horia Racoviceanu * Horihiro Kumagai * Hr.Ladavac * Hsin-Hsiung Chang * Hubert Feyrer * Hubert Tournier * Hugh Mahon * Hugo Leisink * Hung-Chi Chu * Hung-Yi Chen * Hyogeol Lee * IMAI Takeshi * IMAMURA Tomoaki * IWASHITA Yoji * IWATSUKI Hiroyuki * Ian Holland * Ian Struble * Ian Vaudrey * Iblis Lin * Igor Artemiev * Igor Khasilev * Igor Leonenko * Igor Ostapenko * Igor Pokrovsky * Igor Roshchin * Igor Serikov * Igor Sviridov * Igor Vinokurov * Ikuo Nakagawa * Ildar Hizbulin * Ilia Chipitsine * Ilya Khamushkin * Ilya V. Komarov * Ismail Yenigul * Itsuro Saito * Ivan Klymenko * Ivan Rozhuk * Ivan Sharov * Ivan Sviridov * J Shoemaker * J. Bryant * J. David Lowe * J. Han * J. Hawk * J. Randolph * J.R. Oldroyd * J.T. Conklin * Jacek Pelka * Jack * Jackson Low * Jacob Atzen * Jacob Bohn Lorensen * Jacques Marneweck * Jagane D Sundar * Jake Freeland * Jake Hamby * Jake Smith * Jakub Klausa * James Bailie * James Buren * James Clark * James D. Stewart * James E Keenan * James Jegers * James McNaughton * James O'Gorman * James P. Howard, II * James Raftery * James Raynard * James T. Liu * James da Silva * James Wright * Jamie Heckford * Jamie Jones * Jan Conard * Jan Henrik Sylvester * Jan Jungnickel * {jkb} * Jan L. Peterson * Jan Rochel * Jan Siml * Jan Srzednicki * Jan Stocker * Jan-Peter Koopmann * Janaka Wickramasinghe * Janick Taillandier * Janky Jay * János Mohácsi * Janusz Kokot * Jarle Greipsland * Jason Burgess * Jason DiCioccio * Jason Garman * Jason Harris * Jason R. Mastaler * Jason Stone * Jason Thorpe * Jason Wright * Jason Young * Javad Kouhi * Javier Martin Rueda * Jay Fenlason * Jay Krell * Jaye Mathisen * Jaap Akkerhuis * Jean-Baptiste Quenot * Jean Benoit * Jean-Sebastien Roy * Jeanne-Kamikaze * Jeff Bartig * Jeff Brown * Jeff Burchell * Jeff Forys * Jeff Kletsky * Jeff Palmer * Jeffrey Baitis * Jeffrey Evans * Jeffrey H. Johnson * Jeffrey Leung * Jeff Molofee * Jeffrey Wheat * Jens Grassel * Jens Holmqvist * Jens K. Loewe * Jens Rehsack * Jeremy Allison * Jeremy Baggs * Jeremy C. Reed * Jeremy Chatfield * Jeremy Karlson * Jeremy Prior * Jeremy Shaffner * Jeroen Schot * Jerry Eriksson * Jesper Dalberg * Jesper Noehr * Jesse Kempf * Jesse McConnell * Jesse Rosenstock * Jesse Smith * Jesse van den Kieboom * Jia-Wei Ye * Jian-Da Li * Jie Gao * {babb} * Jim Binkley * Jim Bloom * Jim Brown * Jim Carroll * Jim Flowers * Jim Geovedi * Jim Leppek * Jim Lowe * Jim Mattson * Jim Mercer * Jim Ohlstein * Jim Pirzyk * Jim Riggs * Jim Shewmaker * Jim Sloan * Jim Stapleton * Jim Wilson * Jimbo Bahooli * Jin Guojun * Jin-Shan Tseng * Jin-Sih Lin * Jo Rhett * Joachim Kuebart * Joachim Strombergson * Joao Carlos Mendes Luis * Jochen Pohl * Joe Abley * Joe Barbish * Joe Halpin * Joe Holden * Joe Horn * Joe Jih-Shian Lu * Joe Kelsey * Joe Orthoefer * Joe Smith * Joe Traister * Joel Diaz * Joel Faedi * Joel Ray Holveck * Joel Sutton * Joerg Pulz * Joerg Schilling * Johan Granlund * Johan Larsson * Johan Strom * Johann Tonsing * Johannes 5 Joemann * Johannes Grødem * Johannes Helander * Johannes Stille * John Beckett * John Beukema * John Brezak * John Capo * John F. Woods * John Ferrel * John Goerzen * John Heidemann * John Hood * John Kohl * John Lind * John Mackin * John McAree * John MacFarlane * John Mehr * John Merryweather Cooper * John Nielsen * John Oxley * John P * John Perry * John Prather * John Preisler * John Reynolds * John Rochester * John Sadler * John Saunders * John Von Essen * John W. O'Brien * John Wehle * John Woods * Johny Mattsson * Jon Amundsen * Jon Morgan * Jon Nistor * Jon Passki * Jon Stuart * Jon Wilson * Jona Joachim * Jonas Ferreira * Jonathan Belson * Jonathan Bokovza * Jonathan Chen * Jonathan Drews * Jonathan H N Chin * Jonathan Hanna * Jonathan Lennox * Jonathan Liu * Jonathan McDowell * Jonathan Pennington * Jonathan Price * Jordan DeLong * Jordi Haarman * Jorge Goncalves * Jorge M. Goncalves * Joris Vandalon * Jos Backus * Jose Abelardo Martinez * Jose Liang * Jose Marques * Jose Rodriguez * José García Juanino * Josef Grosch * Joseph Haga * Joseph Scott * Joseph Stein * Josh Carroll * Josh Elsasser * Josh Gilliam * Josh Tiefenbach * Josh Tolbert * Joshua D. Abraham * Joshua Goodall * Jostein Trondal * Juan Salaverria * Juha Inkari * Juha Nygard * Juha Ylitalo * Jui-Nan Lin * Jukka A. Ukkonen * Julian Assange * Julian C. Dunn * Julian Coleman * {jhs} * Julian Jenkins * Julian Stecklina * Jun Mukai * Junichi Satoh * Junji NAKANISHI * Junji SAKAI * Junya WATANABE * Justas * Justin Stanford * Jyun-Yan You * Gergely CZUCZY * K.Higashino * KANOU Hiroki * KATO Tsuguru * KIMURA Shigekazu * KUNISHIMA Takeo * Kai Vorma * Kai Wang * Kaleb S. Keithley * Kalle R. Møller * Kan Sasaki * Kaneda Hiloshi * Kang Liu * Kang-ming Liu * Kapil Chowksey * Karel Miklav * Karl Denninger * Karl Dietz * Karl Lehenbauer * Karsten W. Rohrbach * Katalin Konkoly * Katsura Matsumoto * Kawanobe Koh * Kay Abendroth * Kay Lehmann * Kazami * Kazuhito HONDA * Kees Jan Koster * Keith Bostic * Keith E. Walker * Keith Moore * Keith Sklower * Kelley Reynolds * Ken Hornstein * Ken Key * Ken Mayer * Ken McGlothlen * Ken Menzel * Ken Tom * Kenji Rikitake * Kenji Saito * Kenji Takefu * Kenji Tomita * Kenneth Furge * Kenneth Monville * Kenneth R. Westerback * Kenneth Stailey * Kenneth Vestergaard Schmidt * Kent Talarico * Kent Vander Velden * Kentaro Inagaki * Kevin Bracey * Kevin Brunelle * Kevin Day * Kevin Golding * Kevin Lahey * Kevin Meltzer * Kevin Oberman * Kevin Street * Kevin Van Maren * Kevin Zheng * Key-Teck SIN * Khairil Yusof * Killer * Kim Scarborough * Kimura Fuyuki * Kiril Mitev * Kirill Bezzubets * Kirill A. Korinskiy * Kirill Orlov * Kirk Strauser * Kiroh HARADA * Klaus Aehlig * Klaus Goger * Klaus Herrmann * Klaus Klein * Klaus Michael Indlekofer * Klaus-J. Wolf * Koichi Sato * Konrad Heuer * Konrad Lapsz * Konstantin Chuguev * Konstantin Reznichenko * Konstantin Stroikovsky * Konstantinos Mplekos * Kostya Lukin * Kouichi Hirabayashi * Kris Dow * Krzysztof Kowalewski * Krzysztof Pawlowski * Kuan-Chung Chiu * Kuang-che Wu * Kuo-Feng Tseng * Kurt D. Zeilenga * Kurt Kanzenbach * Kurt Olsen * Kyle Martin * Kyung-tak, Yoo * L. Jonas Olsson * Lacey Powers * Lapo Luchini * Larry Altneu * Larry P. Maloney * Lars Bernhardsson * Lars Eggert * Lars Erik Gullerud * Lasse L. Johnsen * Laurence Lopez * Laurent Courty * Laurent Levier * Lauri Watts * Laust S. Jespersen * Leandro Luiz Pereira * Lee Cremeans * Lefteris Chatzibarbas * Leif Pedersen * Len Sassaman * Leo Kim * Leo Vandewoestijne * Leonardo Silveira de A. Martins * Leonhard Wimmer * Leonid Zolotarev * Lev Walkin * Levent Kayan * Lewis Thompson * Li-lun Wang * Liam Foy * Linh Pham * Loganaden Velvindron -* Lon Willett +* Lon Willett * Loren J. Rittle * Loren M. Lang * Louis A. Mamakos * Lowell Gilbert * Lubomir Metodiev Marinov * Lucas Andrade * Lucas James * Lucio Costa * Luiz Eduardo Roncato Cordeiro * Lukasz Komsta * Lukasz Stelmach * Lukasz Wasikowski * Lupe Christoph * Lutz Boehne * Lyndon Nerenberg * M Rothwell * M. L. Dodson * M.C. Wong * MOROHOSHI Akihiko * Machiel Mastenbroek * Magnus Enbom * Mahesh Neelakanta * Mahlon E. Smith * Maja Reberc * Makoto WATANABE * Makoto YAMAKURA * Malte Lance * Manish Jain * Mantas Kaulakys * Manu Iyengar * Manuel Creach * Manuel Rabade Garcia * Marc Blanchet * Marc Frajola * Marc Olzheim * Marc Ramirez * Marc Recht * Marc Silver * Marc Slemko * Marc van Kempen * Marc van Woerkom * Marcel Bischoff * Marcel Kaiser * Marcello Silva Coutinho * Marcelo/Porks Rossi * Marcin Cieslak * Marcin Gondek * Marcin Jessa * Marcin Wisnicki * Marco Molteni * Marco Steinbach * Marco van de Voort * Marcos Andre Hermann * Marcus Vinicius Bastos Leandro * Marek Zarychta * Marin Atanasov * Mario Lobo * Marius Nünnerich * Mark A. Wicks * Mark Andrews * Mark Blackman * Mark Cammidge * Mark Daniel Reidel * Mark Diekhans * Mark Foster * Mark Hannon * Mark Huizer * Mark J. Miller * Mark J. Taylor * Mark Johnston * Mark Kane * Mark Knight * Mark Krentel * Mark Mayo * Mark Starovoytov * Mark Stosberg * Mark Thompson * Mark Tinguely * Mark Treacy * Mark Valentine * Mark Walker * Markus Holmberg * Markus Niemistö * Martijn Lina * Martin Dieringer * Martin Filla * Martin Hinner * Martin Ibert * Martin Jackson * Martin Kammerhofer * Martin Karlsson * Martin Klaffenboeck * Martin Kraft -* Martin Kropfinger [freebsd@rakor-net.de>]> +* Martin Kropfinger ]> * Martin Mersberger * Martin Minkus * Martin Neubauer * Martin Otto * Martin Pala * Martin Preuss * Martin Sugioarto * Martin Tournoij * Martin Waschbüsch * Martti Kuparinen * Marwan Burelle * Masachika ISHIZUKA * Masafumi Otsune * Masahiro Sekiguchi * Masahiro TAKEMURA * Masahiro Teramoto * Masakazu HIGAKI * Masaki TAGAWA * Masanobu Saitoh * Masanori Kanaoka * Masanori Kiriake * Masanori OZAWA * Masashi CHIBA * Masatoshi TAMURA * Matheus Estrela * Mathias Monnerville * Mathieu Simon * Mats Lofkvist * Matt Bartley * Matt Dawson * Matt Douhan * Matt Emmerton * Matt Heckaman * Matt Jibson * Matt Lancereau * Matt Loschert * Matt Mills * Matt Peterson * Matt Smith * Matt Stofko * Matt Thomas * Matt Tosto * Matt White * Matteo Cypriani * Matthew Braithwaite * Matthew C. Mead * Matthew Cashdollar * Matthew Donovan * Matthew Emmerton * Matthew Flatt * Matthew Fuller * Matthew George * Matthew Gibson * Matthew Grooms * Matthew Holder * Matthew Luckie * Matthew Stein * Matthew West * Matthew Will * Matthew X. Economou * Matthias Petermann * Matthias Pfaller * Matthias Scheler * Matthias Schmidt * Matthias Sund * Matthias Schündehütte * Matthias Teege * Matthieu Guegan * Matthieu Volat * Mattias Gronlund * Mattias Pantzare * Matus Uhlar * Maurice Castro * Mauricio Herrera Cuadra * Mauro Risonho de Paula Assumpção * Max Campos * Max E. Kuznecov * Max Euston * Max N. Boyarov * Max V. Kostikov * Maxim Bolotin * Maxim Dounin * Maxim Filimonov * Maxim Ignatenko * Maxim Loginov * Maxim Samsonov * Maxim Tuliuk * Maxime Romano * Meikel Brandmeyer * Mel Flynn * Meno Abels * Meyer Wolfsheim * Mia Rain * Micha Class * Michael A. Kohn * Michael Alyn Miller * Michael Butler * Michael Butschky * Michael C. Shultz * Michael Clay * Michael Collette * Michael Ebert * Michael Edenfield * Michael Galassi * Michael Hancock * Michael Handler * Michael Hohmuth * Michael Iatrou * Michael Lyngbøl * Michael Muenz * Michael Neumann * Michael O. Boev * Michael Perlman * Michael Petry * Michael Ranner * Michael Sanders * Michael Sardo * Michael Schout * Michael Searle * Michael Seyfert * Michael Urban * Michael Vasilenko * Michal Hanula * Michal Listos * Michal Pasternak * Michel Lavondés * Michele Possamai * Michelle Sullivan * Michihiro Satoh * Michio Karl Jinbo * Micho Durdevich * Mickael Maillot * Miguel Angel Sagreras * Miguel Mendez * Mihoko Tanaka * Mij * Mika Nystrom * Mikael Hybsch * Mikael Karpberg * Mike Andrews * Mike Bowie * Mike Bristow * Mike Del * Mike Durian * Mike Durkin * Mike E. Matsnev * Mike Edenfield * Mike Erickson * Mike Evans * Mike Futerko * Mike Grupenhoff * Mike Harding * Mike Hibler * Mike Krutov * Mike Lockwood * Mike McGaughey * Mike Meyer * Mike Mitchell * Mike Murphy * Mike Patterson * Mike Peck * Mike Sherwood * Mike Spengler * Mike Tancsa * Mikhail A. Sokolov * Mikhail T. * Mikhail Zakharov * Mikolaj Rydzewski * Mikolaj Golub * Miks Mikelsons * Milan Obuch * Milosz Galazka * Mina Galić * Ming-I Hseh * Mitsuru Yoshida * Mohammad S. Babaei * Monte Mitzelfelt * Mooneer Salem * Morgan Davis * Morten Slot Kristensen * Mostyn Lewis * Motomichi Matsuzaki * Motoyuki Kasahara * Munish Chopra * Murilo Opsfelder * Mustafa Arif * Mykola Dzham * Mykola Khotyaintsev * Mykola Marzhan * N.G.Smith * Nadilson Ferreira * NAGAO Tadaaki * NAKAJI Hiroyuki * NAKAMURA Kazushi * NAKAMURA Motonori * NIIMI Satoshi * NOKUBI Hirotaka * Nadav Eiron * Nanbor Wang * Naofumi Honda * Naoki Hamada * Naram Qashat * Narayan Namdev Newton * Narvi * Nate Eldredge * Nathan Dorfman * Nathaniel Roark * Natsagdorj Shagdar * Neal Fachan * Neal Nelson * Necati Ersen Siseci * Ned Wolpert * Neil Booth * Nguyen Tam Chinh * Niall Smart * Nicholas Esborn * Nick Barnes * Nick Black * Nick Dewing * Nick Handel * Nick Hilliard * Nick Johnson * Nicole Reid * Nikos Kokkalis * Nick Leuta * Nick Rogness * Nick Williams * Nick Withers * Nicko Dehaine * Nickolay N. Dudorov * Nicolas Embriz * Nicolas Jombart * Niklas Hallqvist * Nikola Lecic * Nikola Kolev * Nikos Ntarmos * Nils M. Holm * Nilton Jose Rizzo * Nisha Talagala * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * No Name * Nobuhiro Yasutomi * Nobuyuki Koganemaru * Norberto Lopes * Norio Suzuki * Noritaka Ishizumi * Noritoshi Demizu * Noriyuki Soda * Oddbjorn Steffensen * Oh Junseon * Olaf Wagner * Olafur Osvaldsson * Oleg Alexeenkov * Oleg Ginzburg * Oleg Kiselyov * Oleg A. Mamontov * Oleg M. Golovanov * Oleg Moskalenko * Oleg R. Muhutdinov * Oleg Semyonov * Oleg Sharoiko * Oleg Ukraincev * Oleg V. Volkov * Oleh Hushchenkov * Oleksandr Lystopad * Olexander Kunytsa * Oliver Breuninger * Oliver Dunkl * Oliver Fischer * Oliver Friedrichs * Oliver Hartmann * Oliver Heesakkers * Oliver Helmling * Oliver Laumann * Oliver Oberdorf * Oliver Peter * Olivier Beyssac * Olivier Tharan * Olof Johansson * Omer Faruk Sen * Oscar Bonilla * Otacílio de Araújo Ramos Neto * Otávio Fernandes * Ozkan KIRIK * Pace Willisson * Paco Rosich * Pakhom Golynga * Panagiotis Astithas * Panagiotis Kritikakos * Parag Patel * Pascal Pederiva * Pascal Vizeli * Pasi Hirvonen * Pasvorn Boonmark * Patrick Alken * Patrick Atamaniuk * Patrick Bihan-Faou * Patrick Dung * Patrick Hausen * Patrick MARIE * Patrick Powell * Patrick Rinke * Patrick Seal * Patrick Tracanelli * Paul * Paul A. Hoadley * Paul Antonov * Paul Chvostek * Paul Dlug * Paul F. Werkowski * Paul Fox * Paul Koch * Paul Kranenburg * Paul M. Lambert * Paul Mackerras * Paul Popelka * Paul S. LaFollette, Jr. * Paul Sandys * Paul Schmehl * Paul T. Root * Paul Vixie * Paulo Fragoso * Paulo Menezes * Paulo Menezes * Pavel Janik * Pavel Novikov * Pavel Pankov * Pavel Timofeev * Pavel Veretennikov * Pavel I Volkov * Pawel Worach * Pedro A M Vazquez * Pengfei JU * Per Wigren * Pete Bentley * Peter Ankerstål * Peter Avalos * Peter Childs * Peter Cornelius * Pete French * Peter Haight * Peter Holub * Peter Klatt * Peter Kolmisoppi * Peter M. Chen * Peter Much * Peter Olsson * Peter Philipp * Peter S. Housel * Peter Schuller * Peter Stubbs * Péter Terbe * Peter Thoenen * Peter Vereshagin * Peter W. Schmiedeskamp * Peter van Dijk * Peter van Heusden * Petr Macek * Petr Rehor * Phil Budne * Phil Maker * Phil Oleson * Phil Phillips * Phil Sutherland * Phil Taylor * Philip Musumeci * Philip Reynolds * Philip Schulz * Philip Stoev * Philippe Hay * Philippe Lefebvre * Philippe Maechler * Philippe Pepiot * Philippe Rocques * Pierre David * Pierre Y. Dampure * Pierre-Paul Lavoie * Pieter Danhieux * Piotr Florczyk * Piotr Rybicki * Piotr Szerman * Pius Fischer * Pomegranate * Pontus Stenetorp * Powerdog Industries * Priit Järv * Prudhvi Krishna * Qiang Guo * Qing Feng * Quentin Baker * Quentin Stievenart * Quinton Dolan * R Joseph Wright * R. Kym Horsell * R Skinner * Radek Kozlowski * Radim Kolar * Radoslav Vasilev * Rafael Mentz Aquino * Rafal Lesniak * Raffaele De Lorenzo * Rainer Duffer * Ralf Friedl * Ralf Gebhart * Ralf van der Enden * Ralf van Dooren * Randal S. Masutani * Randall Hopper * Randall W. Dean * Randy Bush * Rashid N. Achilov * Rasmus Kaj * Raul Pollicino * Razi Khaja * Reed A. Cartwright * Reinier Bezuidenhout * Remington Lang * Remy Card * Renato P. S. Saoud * Revis Zinkov * Ricardas Cepas * Ricardo A. Reis * Riccardo Veraldi * Rich Morin * Rich Wood * Richard Arends * Richard Henderson * Richard Hwang * Richard J Kuhns * Richard Kiss * Richard M. Neswold * Richard Stallman * Richard Straka * Richard Tobin * Richard Wackerbarth * Richard Winkel * Richard Wiwatowski * Rick Fournier * Rick Macklin * Rick van der Zwet * Rihaz Jerrin * Rikka Göring ]> * Roar Pettersen * Rob Austein * Rob Evers * Rob Mallory * Rob Snow * Robert Crossfield * Robert Crowe * Robert D. Thrush * Robert Eckardt * Robert Felber * Robert Gogolok * Robert Kruus * Robert P Ricci * Robert Sanders * Robert Schlotterbeck * Robert Sexton * Robert Shady * Robert Simmons * Robert Swindells * Robert Withrow * Robert Yoder * Robert Zelaya * Roberto Fernandez Cueto * Robin Carey * Robin Elfrink * Robin Schilham * Robin Schoonover * Robson Mantovani * Rod Taylor * Rodrigo Graeff * Roger Hardiman * Roger Olofsson * Roger Leigh * Roland Jesse * Roland Smith * Dr. Rolf Jansen * Roman Neuhauser * Roman Shterenzon * Roman Synyuk * Roman V. Palagin * Roman Y. Bogdanov * Ron Bickers * Ron Lenk * Ron van Daal * Ronald F. Guilmette * Ronald Kuehn * Roselyn Lee * Ross West * Rostislav Krasny * Roy Maples * Ruben * Rudolf Cejka * Rui Lopes * Ruslan Belkin * Ruslan Shevchenko * Russell Jackson * Russell L. Carter * Russell Vincent * Rusty Nejdl * Ryan Frederick * Ryan Grove * Ryan Moe * Ryan T. Dean * Ryan Thompson * Ryan Younce * Ryo MIYAMOTO * Ryo Okamoto * RyoTa SimaMoto * Ryuichiro IMURA * ru M1cRO * SANETO Takanori * SASAKI Shunsuke * SAWADA Mizuki * SPF * SUGIMURA Takashi * SURANYI Peter * Saiful Alam * Sakai Hiroaki * Sakari Jalovaara * Sam Hartman * Samee Shahzada * Samuel Lam * Samuel Tardieu * Samuele Zannoli * Samy Al Bahra * Sander Janssen * Sander Vesik * Sandro Sigala * Sarod Yatawatta * Sascha Biberhofer * Sascha Blank * Sascha Holzleiter * Sascha Klauder * Sascha Wildner * Satoh Junichi * Saulius Menkevicius * Scot Elliott * Scot W. Hetzel * Scott A. Kenney * Scott A. Moberly * Scott Blachowicz * Scott Burris * Scott Flatman * Scott Hazen Mueller * Scott Kleihege * Scott Lambert * Scott Michel * Scott Reynolds * Scott Ullrich * SeaD * Sean McLaughlin * Seamus Venasse * Sebastian Oswald * Sébastian Santoro * Sebastian Schwarz * Sebastian Strollo * Sebastian Yepes * Seiya Yanagita * Serge Gagnon * Serge Negodyuck * Serge V. Vakulenko * Sergei Chechetkin * Sergei S. Laskavy * Sergei Vyshenski * Sergey Akhmatov * Sergey Akifyev * Sergey Anohin * Sergey V. Dyatko * Sergey Gershtein * Sergey Glushchenko * Sergey Kiselev * Sergey Kosyakov * Sergey Lyubka * Sergey Matveev * Sergey N. Vorokov * Sergey Potapov * Sergey Samoyloff * Sergey Shkonda * Sergey V. Dorokhov * Sergey Velichkevych * Sergio Lenzi * Serguei Okladnikov * Shane Ambler * Shane Kinney * Shaun Courtney * Shawn M. Carey * Shell Hung * Shen Chuan-Hsing * Shigeru Yamamoto * Shigio Yamaguchi * Shin'ya Murakami * Shinichiro Komatsu * Shinsuke Matsui * Shinya Esu * Shinya FUJIE * Shuichi Tanaka * Siebrand Mazeland * Sijmen J. Mulder * Silvio Ap Silva * Simeon Simeonov * Simon * Simon Burge * Simon Cornelius P. Umacob * Simon Dick * Simon Lang * Simon Marlow * Simon Olofsson * Simon Peter * Simon Schubert * Simon Shapiro * Simun Mikecin * Sin'ichiro MIYATANI * Slaven Rezic * Snow Chyld * Soochon Radee * Soren Dayton * Soren Debois * Soren Dossing * Soren S. Jorvang * Stan Barber * Stanislav A. Svirid * Stanislav Grozev * Stanislaw Halik * Stanislav Shalunov * Stas Timokhin * Stefan A. Deutscher * Stefan Eggers * Stefan Ehmann * Stefan Grundmann * Stefan Jahn * Stefan Lambrev * Stefan Moeding * Stefan Petri * Stefan Rumetshofer * Stefan Schmidt * Stefan Schwarzer * Stefan Tell * Stefan `Sec` Zehl * Stefano Marinelli * Steffen Fritz * Steffen Mazanek * Steffen Vogelreuter * Steinar Haug * Sten Poldma * Sten Spans * Stepan Zastupov * Stephan Lichtenauer * Stephane Lapie * Stephen Clawson * Stephen F. Combs * Stephen Farrell * Stephen Fisher * Stephen Gunn * Stephen Hocking * Stephen J. Roznowski * Stephen McKay * Stephen Melvin * Stephen Weeks * Stephon Chen * Steve Ames * Steve Bauer * Steve Coltrin * Steve Deering * Steve Franks * Steve Gerakines * Steve Gericke * Steve O'Hara-Smith * Steve Piette * Steve Roome * Steve Schwarz * Steven Enderle * Steven H. Samorodin * Steven Hartland * Steven Honson * Steven McCanne * Steven Plite * Steven Stallion * Steven Wallace * Stig Inge Lea Bjørnsen * Stijn Hoop * Stuart Henderson * Stylianos Sideridis * Sue Blake * Sugimoto Sadahiro * Sugiura Shiro * Sujal Patel * Sulev-Madis Silber * Sune Stjerneby * Sungman Cho * Sutra Zhou * Suzuki Yoshiaki * Svein Skogen * Sven Klose * Sven Mohr * Svyatoslav Lempert * Sybolt de Boer * TAKAHASHI Kaoru * TERAMOTO Masahiro * Tadashi Kumano * Taguchi Takeshi * Takahiro Yugawa * Takashi Mega * Takashi Uozu * Takayuki Ariga * Takayuki Nakao * Takeru NAIKI * Takeshi Amaike * Takeshi MUTOH * Takeshi Ohashi * Takeshi WATANABE * Takuya SHIOZAKI * Talal Al Dik * Tanja Wittke * Tarasov Alexey * Tassilo Philipp * Tatoku Ogaito * Tatsuki Makino * Tatsuya Kudoh * Tatsuya Ueda * Taylor Dondich * Ted Buswell * Ted Faber * Ted Lemon * Ted Stodgell * Teodor Sigaev * Terry Lambert * Terry Lee * Terry Sposato * Teruaki Ata * Tetsuro Yabu * Tetsuya Furukawa * Thaddeus Covert * Theo de Raadt * Thierry Dussuet * Thomas * Thomas A. Stephens * Thomas Bartelmess * Thomas BRETON * Thomas Cort * Thomas D. Dean * Thomas David Rivers * Thomas Dreibholz * Thomas G. McWilliams * Thomas Hurst * Thomas Kempka * Thomas König * Thomas M. Hermann * Thomas Melzer * Thomas Ptacek * Thomas Spreng * Thomas Stromberg * Thomas Valentino Crimi * Thomas Vogt * Thorsten Greiner * Þórður Ívarsson * Tillman Hodgson * Tim Daneliuk * Tim Hemel * Tim Little * Tim Niemueller * Tim Pozar * Tim Singletary * Tim Welch * Tim Wilkinson * Timo J. Rinne * Timofeev Vladimir * Timothy Beyer * Timothy Bourke * Timothy Jensen * Timothy Redaelli * Ting-Wei Lan * Tobias Begalke * Tobias Reifenberger * Tobias Roth * Toby Allsopp * Todd Miller * Todd Mortensen * Tofig Suleymanov * Tom * Tom Carrick * Tom Gray - DCA * Tom Jobbins * Tom Mortensen * Tom Mueller-Kortkamp * Tom Pusateri * Tom Rush * Tom Samplonius * Tomas Verbaitis * Tomasz Walaszek * Tomaž Muraus * Tomek Cedro * Tomohiko Kurahashi * Tomoyuki Sakurai * Toni Andjelkovic * Toni Gundogdu * Toni Viemero * Toni Yannick Kalombo * Tony Kimball * Tony Li * Tony Lynn * Tony Maher * Tony Shadwick * Tor Halvard "Squat" Furulund * Torbjorn Granlund * Toshiharu Ohno * Toshihiko SHIMOKAWA * Toshihiro Kanda * Toshiomi Moriki * Toshiya SAITOH * Travis Campbell * Travis Poppe * Trefor S. * Trenton Schulz * Trevor Blackwell * Trevor Cornpropst * Trober * Troels Kofoed Jacobsen * Trond Endrestøl * Tsung-Han Yeh * Tz-Huan Huang * Tzanetos Balitsaris * UMENO Takashi * URATA Shuichiro * Udo Schweigert * Uffe Jakobsen * Ugo Paternostro * Ulf Kieber * Ulli Linzen * Ullrich Franke * Uwe Arndt * Uwe Pierau * Vaggelis Typaldos * Vadim Belman * Vadim Chekan * Vadim Goncharov * Vadim Kolontsov * Vadim Kurland * Vadim Mikhailov * Vaida Bogdan * Vaidas Zlotkus * Valentin Nechayev * Valentin Zahariev * Valery Komarov * Van Jacobson * Vany Serezhkin * Vaclav Haisman * Vasek Balcar * Vasily V. Grechishnikov * Vasim Valejev * Vassili Tchersky * Vernon J. Schryver * Veselin Slavov * Viacheslav Mikerov * Vic Abell * Victor Cruceru * Victor Popov * Victor Semionov * Vidar Karlsen * Viktor Fomichev * Ville Eerola * Vince Valenti * Vincent DEFERT * Vincent Poy * Vincent Tantardini * Vincenzo Capuano * Virgil Champlin * Vitaly Magerya * Vivek Khera * Vlad GALU * Vlad V. Teterya * Vladimir A. Jakovenko * Vladimir Chukharev * Vladimir Gorelov * Vladimir Grebenshchikov * Vladimir Kurtikov * Vladimir Kushnir * Vladimir Osintsev * Vladimir Savichev * Volker Theile * Volker Quetschke * Volodymyr Kostyrko * Vsevolod Lobko * Vyacheslav Anikin * Vyacheslav Ivanchenko * Vyacheslav Olkhovchenkov * W. Gerald Hicks * W. Richard Stevens * Waitman Gobble * Walt Howard * Walt M. Shandruk * Walter Hop * Walter Venable * Warren Toomey * Watanabe Kazuhiro * Wayne Scott * Wei-Hao Syu * Wei-Yu Chen * Wendell Borges * Wei Guo * Wei Zhao * Werner Griessl * Wes Santee * Wietse Venema * Wiljo Heinen * Willem Jan Withagen * Willem van Engen * William Jolitz * William Josephson * William Liao * Wojtek Pilorz * Wolfgang Helbig * Wolfgang Solfrank * {wolf} * Woodchuck Dave * Woody Carey * Wouter Van Hemel * Wu Ching-hong * {wylie} * Xavier Beaudouin * Xiaoding Liu * Yamagi Burmeister * Yanhui Shen * Yann Berthier * Yannis Kotsinos * Yarema * Yaroslav Terletsky * Yasuhiro Fukama * Yasuhito FUTATSUKI * Yen-Shuo Su * Yi-Feng Tzeng * Yi-Hsuan Hsin * Ying-Chieh Chen * Yinghong Liu * Yixin Jin * Yoichi Asai * Yoshiaki Uchikawa * Yoshihiko SARUMRU * Yoshihisa NAKAGAWA * Yoshikazu Goto * Yoshimasa Ohnishi * Yoshishige Arai * Yu-Shun Wang * Yuan-Chung Hsiao * Yuan Jue * Yuichi MATSUTAKA * Yuichiro AIZAWA * Yuichiro NAITO * Yujiro MIYATA * Yuki SHIMAZU * Yuri Kurenkov * Yuriy N. Shkandybin * Yuriy Tsibizov * Yusuke Nawano * Yu-Xi Lim * Yuu Yashiki * Yuuichi Narahara * Yuuki SAWADA * Yuukis * Yuval Yarom * Yves Fonk * Yves Fonk * Zach Garner * Zach Heilig * Zach Thompson * Zach Zurflu * Zachariah Thompson * Zak Johnson * Zane C. Bowers * Zhen REN * Zhihao Yuan * Zhixiang JIANG * Zhong Ming-Xun * Zoltán Király * appleboy * arci * ayunyan * der Mouse * geoffroy desvernay * gspu * lightside * mew14930xvi * rossiya