BOOTHD(8)
π BOOTHD π (that's section 8, bestie)
Okay so boothd is the Booth Cluster Ticket Manager, and no it's not about photo booths, it's about tickets and it's lowkey iconic. Let's get into it. π
β¨ NAME β¨
boothd β The Booth Cluster Ticket Manager. She's the moment. π
πΈ SYNOPSIS πΈ
boothd daemon [-SD] [-c config] [-l lockfile]
booth list [-s site] [-c config]
booth grant [-s site] [-c config] [-FCw] ticket
booth revoke [-s site] [-c config] [-w] ticket
booth peers [-s site] [-c config]
booth status [-D] [-c config]
π¦ DESCRIPTION π¦
So bestie, here's the tea β β Booth manages tickets, and those tickets are literally what gives one of the cluster sites permission to run certain resources. Which sites, you ask? The ones spread out over geographically dispersed distances, iykyk. The whole point is that it's designed to extend Pacemaker so Pacemaker can handle geographically distributed clustering. πΊοΈβ¨
It's based on the RAFT protocol, and if you wanna read the actual paper, here's the link, fr fr:
https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf
Go read it, it's giving academic but make it slay. π
π SHORT EXAMPLES π
Quick lil taste test, no cap:
# boothd daemon -D
# booth list
# booth grant ticket-nfs
# booth revoke ticket-nfs
Look at that. Chef's kiss. ππ
π OPTIONS π
Okay the whole menu, item by item, I did not skip a single one because I love you:
-cconfigfile β The config to use, bestie. It can be a full path to a configuration file, or a short name. If you give it a short name, then the directory/etc/boothgets prepended and the suffix.confgets appended. Per default,boothis used, which results in the path/etc/booth/booth.conf. Also β plot twist β the configuration name also determines the name of the PID file. For the defaults, that's/var/run/booth/booth.pid.-sβ Site address or name. π There's a special valueotherthat you can use to specify the other site. Obviously, if you do that, the booth configuration must have exactly two sites defined. Two. That's it. Don't be greedy.-Fβ immediate grant: Don't wait for unreachable sites to relinquish the ticket. See the Booth ticket management section below for more details, bestie. For manual tickets this option allows one to grant a ticket which is currently granted β see the Manual tickets section below for the deets.
β οΈ This option may be DANGEROUS. It makes booth grant the ticket even though it cannot ascertain that unreachable sites don't hold the same ticket. It is up to you, the user, to make sure that unreachable sites don't have this ticket as granted. Not me being dramatic, it literally says dangerous. π
-wβ wait for the request outcome: the client waits for the final outcome of thegrantorrevokerequest. No cutting to the chase, we wait. β³-Cβ wait for ticket commit to CIB: the client waits for the ticket commit to CIB (only forgrantrequests). And heads up: if one or more sites are unreachable, this takes the ticket expire time (plus, if defined, the acquire-after time). So like, pack a snack. π-h,--helpβ Give a short usage output. Short and sweet, respect. π«Ά--versionβ Report version information. Tell me what you are, king. π-Sβ systemd mode: don't fork. This disables daemonizing, and the process will remain in the foreground. Very demure, very mindful, stays right there. β¨-Dβ Increases the debug output level. Turn the volume up, she's yapping (in a useful way). π₯-llockfile β Use another lock file. By default, the lock file name is inferred from the configuration file name. Normally not needed. It's giving optional, it's giving extra. π
π COMMANDS π
Little known fact: whether the binary is called as boothd or booth doesn't matter at all. The first argument is what determines the mode of operation. Main character energy is decided by vibes, not by name. π
daemonβ Tellsboothdto serve a site. The locally configured interfaces are searched for an IP address that is defined in the configuration. Thenboothruns in either/arbitrator/or/site/mode. Pick a lane, babe. π°οΈclientβ Booth clients can list the ticket information (see alsocrm_ticket -L), and revoke or grant tickets to a site.
The grant and, under certain circumstances, revoke operations may take a while to return a definite operation's outcome. The client will wait up to the network timeout value (by default 5 seconds) for the result. Unless the -w option was set, in which case the client waits indefinitely. Indefinitely!! She's committed. π
In this mode the configuration file is searched for an IP address that is locally reachable β like, it matches a configured subnet. This allows one to run the client commands on another node in the same cluster, as long as the config file and the service IP is locally reachable.
For instance, if the booth service IP is 192.168.55.200, and the local node has 192.168.55.15 configured on one of its network interfaces, it knows which site it belongs to. She just knows. π§
Use -s to direct the client to connect to a different site.
statusβboothdlooks for the (locked) PID file and the UDP socket, prints some output tostdout(for use in shell scripts) and returns an OCF-compatible return code. With-D, a human-readable message is printed toSTDERRas well. Perfect for your scripts, and perfect for your eyeballs. πpeersβ List the otherboothdservers we know about. π―
In addition to the type, name (IP address), and the last time the server was heard from, network statistics are also printed. The statistics are split into two rows β the first one consists of counters for the sent packets, and the second one for the received packets. The first counter is the total number of packets, and descriptions of the other counters follows:
resendsβ Packets which had to be resent because the recipient didn't acknowledge a message. This usually means that either the message or the acknowledgement got lost. The number of resends usually reflect the network reliability. So if this is high... the network is giving flaky. πerrorβ Packets which either couldn't be sent, got truncated, or were badly formed. Should be zero. ZERO. If it's not zero we have a problem.invalidβ These packets contain either invalid or non-existing ticket name or refer to a non-existing ticket leader. Should be zero. Again. Zero. Please. πauthfailβ Packets which couldn't be authenticated. Should be zero. Stop it. π«
still more to come, bestie β don't go anywhere β¨
π CONFIGURATION FILE π
bestie listen up because this one is non-negotiable: the configuration file has to be identical on all sites and arbitrators. all of them. no exceptions, no "oh I'll just tweak mine a lil", periodt. π
a minimal file can look like this:
site="192.168.201.100"
site="192.168.202.100"
arbitrator="192.168.203.100"
ticket="ticket-db8"
comments? they start with a hash-sign (#). and all that whitespace at the start and end of a line, plus the space around the =, it's all ignored, we don't care, it's giving chill. π¦
here's the whole menu of key/value pairs, in order:
portβ the UDP/TCP port to use. default is 9929.transportβ the transport protocol used for Raft exchanges. currently only UDP is supported. heads up tho π: clients talk TCP to a daemon, so Booth will always bind and listen on both UDP and TCP ports.authfileβ the file holding the authentication key. the key can be binary or text. if it's text, then leading and trailing white space (newlines included) gets ignored. this key is a shared secret and it's used to authenticate both clients and servers. it must be between 8 and 64 characters long, and be readable only by the file owner. πmaxtimeskewβ anti-replay-attack armor π‘οΈ: packets carry generation timestamps, and a timestamp isn't allowed to be too old. this parameter says how old is too old. value is in seconds, default is 600 (10 minutes). if clocks vary more than that default between sites and nodes (which, btw, is definitely something you should fix) then bump this higher. the time skew test only happens in concert with authentication.debugβ sets the debug output level. it's the alternative to the command line argument, and it's only effective for daemon mode of operation.siteβ defines a site Raft member with the given IP. sites can acquire tickets, and their IP should be managed by the cluster.arbitratorβ defines an arbitrator Raft member with the given IP. arbitrators help reach consensus in elections and cannot hold tickets.
lowkey important: Booth needs at least three members for normal operation, and an odd number of members provides more redundancy. β¨
site-user,site-group,arbitrator-user,arbitrator-groupβ these define the credentials boothd will be running with. on a (Pacemaker) site the booth process has to callcrm_ticket, so the default there is to usehacluster:'haclient'; for an arbitrator this user and group might not exist, so there we default tonobody:'nobody'.ticketβ registers a ticket. multiple tickets can be handled by a single Booth instance. use the special ticket name__defaults__to modify the defaults β and the__defaults__stanza must precede all the other ticket specifications. π
and now, the ticket-level goodies. all times are in seconds β±οΈ:
expireβ the lease time for a ticket. after that time, the ticket can be acquired by another site if the ticket holder isn't reachable. default is 600.acquire-afterβ once a ticket is lost, wait this much time in addition before acquiring the ticket. it exists so the site that lost the ticket has room to relinquish the resources, by either stopping them or fencing a node. a typical delay might be 60 seconds, but ultimately it depends on the protected resources and the fencing configuration. default is 0.renewal-freqβ set the ticket renewal frequency period. if the network reliability is often reduced over prolonged periods, it's advisable to try to renew more often. before every renewal, if defined, the command or commands specified inbefore-acquire-handlerare run β in which caserenewal-freqis effectively also the local cluster monitoring interval.timeoutβ after that time booth will re-send packets if there was an insufficient number of replies. it should be long enough to let packets reach other members. default is 5.retriesβ how many times to retry sending packets before giving up waiting for acks from other members. default is 10, and values lower than 3 are illegal. π« ticket renewals should allow for this number of retries, so the total retry time must be shorter than the renewal time (either half the expire time orrenewal-freq):
timeout*(retries+1) < renewal
weightsβ a comma-separated list of integers defining the weight of individual Raft members, in the same order as thesiteandarbitratorlines. default is 0 for all, which means the order in the configuration file defines priority for conflicting requests.before-acquire-handlerβ if set, this specifies either a file containing a program to run, or a directory where a number of programs can reside. they get invoked before boothd tries to acquire or renew a ticket, and if any of them exits with a code other than 0, boothd relinquishes the ticket. so it's how you make sure the services and their dependencies protected by the ticket are actually in good shape at this site. for instance, if a service in the dependency-chain has a failcount of INFINITY on all available nodes, the service will be unable to run β and in that case, it is of no use to claim the ticket. one or more arguments may follow the program or directory location; typically there's at least the name of one of the resources which depend on this ticket. see below for details about booth specific environment variables. the distributedservice-runnablescript is an example which may be used to test whether a pacemaker resource can be started.attr-prereqβ sites can have GEO attributes managed with thegeostore(8)program. attributes are within a ticket's scope and may be tested by boothd for additional control of ticket failover (automatic) or ticket acquire (manual). attributes are typically used to convey extra information about resources, for instance database replication status, and they're commonly updated by resource agents. attribute values are referenced in expressions and may be tested for equality with theeqbinary operator, or inequality with theneoperator. the usage goes like this:
attr-prereq = <grant_type> <name> <op> <value>
<grant_type>: "auto" | "manual"
<name>: attribute name
<op>: "eq" | "ne"
<value>: attribute value
the two grant types are auto for ticket failover and manual for grants using the booth client. only in case the expression evaluates to true can the ticket be granted. ngl, it's not clear whether the manual grant type has any practical use, because β obviously β this operation is anyway controlled by a human. π and note that there can be no guarantee on whether an attribute value is up to date, i.e. if it actually reflects the current state.
modeβ specifies if the ticket is manual or automatic. by default all tickets are automatic (that is, they are fully controlled by the Raft algorithm). assign the strings"manual"or"MANUAL"to define the ticket as manually controlled.
and here's one example of a booth configuration file, iconic behavior only π:
transport = udp
port = 9930
# D-85774
site="192.168.201.100"
# D-90409
site="::ffff:192.168.202.100"
# A-1120
arbitrator="192.168.203.100"
ticket="ticket-db8"
expire = 600
acquire-after = 60
timeout = 10
retries = 5
renewal-freq = 60
before-acquire-handler = /usr/share/booth/service-runnable db8
attr-prereq = auto repl_state eq ACTIVE
ποΈ BOOTH TICKET MANAGEMENT ποΈ
the booth cluster guarantees that every ticket is owned by only one site at the time. no sharing, no splitting, that's the whole point bestie. π
tickets must be initially granted with the booth client grant command. once it gets granted, the ticket is managed by the booth cluster β hence, only granted tickets are managed by booth.
if the ticket gets lost, i.e. the other members of the booth cluster don't hear from the ticket owner for a sufficiently long time, one of the remaining sites will acquire the ticket. that's what we call ticket failover. β¨
if the remaining members cannot form a majority, then the ticket cannot fail over. (majority or nothing, fr fr.)
a ticket may be revoked at any time with the booth client revoke command. for revoke to succeed, the site holding the ticket must be reachable.
once the ticket is administratively revoked, it is not managed by the booth cluster anymore. for the booth cluster to start managing the ticket again, it must be again granted to a site.
the grant operation, in case not all sites are reachable, may get delayed for the ticket expire time (and, if defined, the acquire-after time). the reason is that the other booth members may not know if the ticket is currently granted at the unreachable site.
this delay may be disabled with the -F option. in that case, it is up to the administrator to make sure that the unreachable site is not holding the ticket. π
when the ticket is managed by booth, it is dangerous to modify it manually using eithercrm_ticketcommand orcrm site ticket. neither of these tools is aware of booth and, consequently, booth itself may not be aware of any ticket status changes. a notable exception is setting the ticket to standby, which is typically done before a planned failover. π
π NOTES π
- tickets are not meant to be moved around quickly β the default expire time is 600 seconds (10 minutes).
- booth works with both IPv4 and IPv6 addresses. π
- booth renews a ticket before it expires, to account for possible transmission delays. the renewal time, unless explicitly set, is set to half the expire time.
π§ HANDLERS π§
currently, there's only one external handler defined (see the before-acquire-handler configuration item above).
the following environment variables are exported to the handler:
BOOTH_TICKETβ the ticket name, as given in the configuration file. (seeticketitem above.)BOOTH_LOCALβ the local site name, as defined insite.BOOTH_CONF_PATHβ the path to the active configuration file.BOOTH_CONF_NAMEβ the configuration name, as used by the-ccommandline argument.BOOTH_TICKET_EXPIRESβ when the ticket expires (in seconds since 1.1.1970), or 0.
the handler is invoked with positional arguments specified after it. π«Ά
π FILES π
/etc/booth/booth.confβ the default config file name, bestie. Yes, that one right there. The-cargument can point you somewhere else (that's back up in OPTIONS, go peek π )./etc/booth/authkeyβ okay so there's no default for this one, but this is the typical hangout spot for the shared secret, aka the authentication key. π/var/run/booth/β the directory holding the PID/lock files. Thestatuscommand also lives in this neighborhood, so like, iykyk. β¨
π RAFT IMPLEMENTATION π
Okay so the whole vibe in one sentence: every ticket corresponds to a separate Raft cluster. Periodt. π¦
And a ticket gets granted to the Raft Leader, and that Leader then owns (or keeps) the ticket. Main character energy only. π
βοΈ ARBITRATOR MANAGEMENT βοΈ
So the booth daemon for an arbitrator β which, lowkey, typically doesn't run the cluster stack at all β can be started through systemd, or with /etc/init.d/booth-arbitrator, depending on which init system the platform supports. Depends on your platform's whole personality fr fr.
The SysV init script starts a booth arbitrator for every single configuration file it finds in /etc/booth. Not one, not two β all of them. π
Platforms running systemd can enable and start every configuration separately using systemctl, like this:
# systemctl enable booth@<configurationname>
# systemctl start booth@<configurationname>
And yes, systemctl requires the configuration name β even for the default name booth. No shortcuts, bestie, it needs the name. π
ποΈ MANUAL TICKETS ποΈ
Manual tickets let users create and manage tickets that booth then handles without the Raft algorithm. Granting and revoking manual tickets? Fully controlled by the administrator, no middleman. And yes, you can define a number of manual and normal tickets in one GEO cluster. Mix and match, we love range. β¨
The automatic ticket management that the Raft algorithm brings is not applied to manually controlled tickets. Specifically, there is no elections, no automatic failover procedures, and no term expiration. None. Zero. Nada. π
But β booth does control whether a ticket is currently being granted to any site, and it warns the user appropriately. So you're not flying blind, bestie. π«Ά
Tickets that were manually granted to a site will remain there until they are manually revoked. Even if a site goes offline, the ticket will not move to another site. And honestly? That's the point. This behavior lets administrators make sure some services stay in a particular site and won't get relocated to another site, possibly one sitting in a totally different geographical location. πΊοΈ
Also: configuring only manual tickets in a GEO cluster means you can have just two sites in a cluster, with no arbitrator needed. That's possible because there's no automatic elections and no voting performed for manual tickets. Two-site glow-up. π
Manual tickets are defined in a configuration file by adding a mode ticket parameter and setting it to manual or MANUAL:
ticket="manual-ticket"
[...]
mode = manual
[...]
Manual tickets can be granted and revoked by using the normal grant and revoke commands, with the usual flags and parameters. The only difference? Specifying the -F flag during a grant command forces a site to become the leader of the specified ticket β even if the ticket is granted to another site. Big move. π₯
π¦ EXIT STATUS π¦
0β Success. And for thestatuscommand specifically: Daemon running. π1(PCMK_OCF_UNKNOWN_ERROR) β the general error code. The "something went sideways" of it all.7(PCMK_OCF_NOT_RUNNING) β no daemon process for that configuration is active. She's not home. π
π BUGS π
Booth is tested regularly β check the README-testing file for more info. We're diligent, okay? π
Please report any bugs either at GitHub:
https://github.com/ClusterLabs/booth/issues
Or, if you prefer bugzilla, at openSUSE bugzilla (component "High Availability"):
https://bugzilla.opensuse.org/enter_bug.cgi?product=openSUSE%20Factory
βοΈ AUTHOR βοΈ
boothd was originally written (mostly) by Jiaju Zhang.
In 2013 and 2014, Philipp Marek took over maintainership.
Since April 2014 it has been mainly developed by Dejan Muhamedagic.
And so many people contributed β see the AUTHORS file. It takes a village, fr fr. π«Ά
π RESOURCES π
- GitHub:
https://github.com/ClusterLabs/booth - Documentation:
http://doc.opensuse.org/products/draft/SLE-HA/SLE-ha-guide_sd_draft/cha.ha.geo.html
π COPYING π
Copyright Β© 2011 Jiaju Zhang <jjzhang@suse.de>
Copyright Β© 2013-2014 Philipp Marek <philipp.marek@linbit.com>
Copyright Β© 2014 Dejan Muhamedagic <dmuhamedagic@suse.com>
Free use of this software is granted under the terms of the GNU General Public License (GPL) as of version 2 (see the COPYING file) or later. Slay, legally. π
okay bestie that's the whole entire page, we made it, icon behavior honestly π this was BOOTHD(8) β section 8 of the manual, the version dated 2026-02-03 β go forth and keep your cluster alive, mwah πβ¨πΈ
π¦ where this page comes from
- ubuntu resolute: booth 1.2-3ubuntu2 Β· GPL-2.0-or-later
- ubuntu stonking: booth 1.2-3ubuntu2 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms