4 \chapter{Storage Daemon Design}
6 \index{Storage Daemon Design }
7 \index{Design!Storage Daemon }
8 \addcontentsline{toc}{section}{Storage Daemon Design}
10 This chapter is intended to be a technical discussion of the Storage daemon
11 services and as such is not targeted at end users but rather at developers and
12 system administrators that want or need to know more of the working details of
15 This document is somewhat out of date.
17 \section{SD Design Introduction}
18 \index{Introduction!SD Design }
19 \index{SD Design Introduction }
20 \addcontentsline{toc}{section}{SD Design Introduction}
22 The Bacula Storage daemon provides storage resources to a Bacula installation.
23 An individual Storage daemon is associated with a physical permanent storage
24 device (for example, a tape drive, CD writer, tape changer or jukebox, etc.),
25 and may employ auxiliary storage resources (such as space on a hard disk file
26 system) to increase performance and/or optimize use of the permanent storage
29 Any number of storage daemons may be run on a given machine; each associated
30 with an individual storage device connected to it, and BACULA operations may
31 employ storage daemons on any number of hosts connected by a network, local or
32 remote. The ability to employ remote storage daemons (with appropriate
33 security measures) permits automatic off-site backup, possibly to publicly
34 available backup repositories.
36 \section{SD Development Outline}
37 \index{Outline!SD Development }
38 \index{SD Development Outline }
39 \addcontentsline{toc}{section}{SD Development Outline}
41 In order to provide a high performance backup and restore solution that scales
42 to very large capacity devices and networks, the storage daemon must be able
43 to extract as much performance from the storage device and network with which
44 it interacts. In order to accomplish this, storage daemons will eventually
45 have to sacrifice simplicity and painless portability in favor of techniques
46 which improve performance. My goal in designing the storage daemon protocol
47 and developing the initial prototype storage daemon is to provide for these
48 additions in the future, while implementing an initial storage daemon which is
49 very simple and portable to almost any POSIX-like environment. This original
50 storage daemon (and its evolved descendants) can serve as a portable solution
51 for non-demanding backup requirements (such as single servers of modest size,
52 individual machines, or small local networks), while serving as the starting
53 point for development of higher performance configurable derivatives which use
54 techniques such as POSIX threads, shared memory, asynchronous I/O, buffering
55 to high-speed intermediate media, and support for tape changers and jukeboxes.
58 \section{SD Connections and Sessions}
59 \index{Sessions!SD Connections and }
60 \index{SD Connections and Sessions }
61 \addcontentsline{toc}{section}{SD Connections and Sessions}
63 A client connects to a storage server by initiating a conventional TCP
64 connection. The storage server accepts the connection unless its maximum
65 number of connections has been reached or the specified host is not granted
66 access to the storage server. Once a connection has been opened, the client
67 may make any number of Query requests, and/or initiate (if permitted), one or
68 more Append sessions (which transmit data to be stored by the storage daemon)
69 and/or Read sessions (which retrieve data from the storage daemon).
71 Most requests and replies sent across the connection are simple ASCII strings,
72 with status replies prefixed by a four digit status code for easier parsing.
73 Binary data appear in blocks stored and retrieved from the storage. Any
74 request may result in a single-line status reply of ``{\tt 3201\ Notification\
75 pending}'', which indicates the client must send a ``Query notification''
76 request to retrieve one or more notifications posted to it. Once the
77 notifications have been returned, the client may then resubmit the request
78 which resulted in the 3201 status.
80 The following descriptions omit common error codes, yet to be defined, which
81 can occur from most or many requests due to events like media errors,
82 restarting of the storage daemon, etc. These details will be filled in, along
83 with a comprehensive list of status codes along with which requests can
84 produce them in an update to this document.
86 \subsection{SD Append Requests}
87 \index{Requests!SD Append }
88 \index{SD Append Requests }
89 \addcontentsline{toc}{subsection}{SD Append Requests}
93 \item [{append open session = \lt{}JobId\gt{} [ \lt{}Password\gt{} ] }]
95 A data append session is opened with the Job ID given by {\it JobId} with
96 client password (if required) given by {\it Password}. If the session is
97 successfully opened, a status of {\tt 3000\ OK} is returned with a ``{\tt
98 ticket\ =\ }{\it number}'' reply used to identify subsequent messages in the
99 session. If too many sessions are open, or a conflicting session (for
100 example, a read in progress when simultaneous read and append sessions are
101 not permitted), a status of ``{\tt 3502\ Volume\ busy}'' is returned. If no
102 volume is mounted, or the volume mounted cannot be appended to, a status of
103 ``{\tt 3503\ Volume\ not\ mounted}'' is returned.
105 \item [append data = \lt{}ticket-number\gt{} ]
107 If the append data is accepted, a status of {\tt 3000\ OK data address =
108 \lt{}IPaddress\gt{} port = \lt{}port\gt{}} is returned, where the {\tt
109 IPaddress} and {\tt port} specify the IP address and port number of the data
110 channel. Error status codes are {\tt 3504\ Invalid\ ticket\ number} and {\tt
111 3505\ Session\ aborted}, the latter of which indicates the entire append
112 session has failed due to a daemon or media error.
114 Once the File daemon has established the connection to the data channel
115 opened by the Storage daemon, it will transfer a header packet followed by
116 any number of data packets. The header packet is of the form:
118 {\tt \lt{}file-index\gt{} \lt{}stream-id\gt{} \lt{}info\gt{}}
120 The details are specified in the
121 \ilink{Daemon Protocol}{_ChapterStart2} section of this
124 \item [*append abort session = \lt{}ticket-number\gt{} ]
126 The open append session with ticket {\it ticket-number} is aborted; any blocks
127 not yet written to permanent media are discarded. Subsequent attempts to
128 append data to the session will receive an error status of {\tt 3505\
131 \item [append end session = \lt{}ticket-number\gt{} ]
133 The open append session with ticket {\it ticket-number} is marked complete; no
134 further blocks may be appended. The storage daemon will give priority to
135 saving any buffered blocks from this session to permanent media as soon as
138 \item [append close session = \lt{}ticket-number\gt{} ]
140 The append session with ticket {\it ticket} is closed. This message does not
141 receive an {\tt 3000\ OK} reply until all of the content of the session are
142 stored on permanent media, at which time said reply is given, followed by a
143 list of volumes, from first to last, which contain blocks from the session,
144 along with the first and last file and block on each containing session data
145 and the volume session key identifying data from that session in lines with
146 the following format:
148 {\tt {\tt Volume = }\lt{}Volume-id\gt{} \lt{}start-file\gt{}
149 \lt{}start-block\gt{} \lt{}end-file\gt{} \lt{}end-block\gt{}
150 \lt{}volume-session-id\gt{}}where {\it Volume-id} is the volume label, {\it
151 start-file} and {\it start-block} are the file and block containing the first
152 data from that session on the volume, {\it end-file} and {\it end-block} are
153 the file and block with the last data from the session on the volume and {\it
154 volume-session-id} is the volume session ID for blocks from the session
155 stored on that volume.
158 \subsection{SD Read Requests}
159 \index{SD Read Requests }
160 \index{Requests!SD Read }
161 \addcontentsline{toc}{subsection}{SD Read Requests}
165 \item [Read open session = \lt{}JobId\gt{} \lt{}Volume-id\gt{}
166 \lt{}start-file\gt{} \lt{}start-block\gt{} \lt{}end-file\gt{}
167 \lt{}end-block\gt{} \lt{}volume-session-id\gt{} \lt{}password\gt{} ]
169 where {\it Volume-id} is the volume label, {\it start-file} and {\it
170 start-block} are the file and block containing the first data from that
171 session on the volume, {\it end-file} and {\it end-block} are the file and
172 block with the last data from the session on the volume and {\it
173 volume-session-id} is the volume session ID for blocks from the session
174 stored on that volume.
176 If the session is successfully opened, a status of
178 {\tt {\tt 3100\ OK Ticket\ =\ }{\it number}``}
180 is returned with a reply used to identify subsequent messages in the session.
181 If too many sessions are open, or a conflicting session (for example, an
182 append in progress when simultaneous read and append sessions are not
183 permitted), a status of ''{\tt 3502\ Volume\ busy}`` is returned. If no
184 volume is mounted, or the volume mounted cannot be appended to, a status of
185 ''{\tt 3503\ Volume\ not\ mounted}`` is returned. If no block with the given
186 volume session ID and the correct client ID number appears in the given first
187 file and block for the volume, a status of ''{\tt 3505\ Session\ not\
188 found}`` is returned.
190 \item [Read data = \lt{}Ticket\gt{} \gt{} \lt{}Block\gt{} ]
192 The specified Block of data from open read session with the specified Ticket
193 number is returned, with a status of {\tt 3000\ OK} followed by a ''{\tt
194 Length\ =\ }{\it size}`` line giving the length in bytes of the block data
195 which immediately follows. Blocks must be retrieved in ascending order, but
196 blocks may be skipped. If a block number greater than the largest stored on
197 the volume is requested, a status of ''{\tt 3201\ End\ of\ volume}`` is
198 returned. If a block number greater than the largest in the file is
199 requested, a status of ''{\tt 3401\ End\ of\ file}`` is returned.
201 \item [Read close session = \lt{}Ticket\gt{} ]
203 The read session with Ticket number is closed. A read session may be closed
204 at any time; you needn't read all its blocks before closing it.
208 \elink{John Walker}{http://www.fourmilab.ch/}
211 \section{SD Data Structures}
212 \index{SD Data Structures}
213 \addcontentsline{toc}{section}{SD Data Structures}
215 In the Storage daemon, there is a Device resource (i.e. from conf file)
216 that describes each physical device. When the physical device is used it
217 is controled by the DEVICE structure (defined in dev.h), and typically
218 refered to as dev in the C++ code. Anyone writing or reading a physical
219 device must ultimately get a lock on the DEVICE structure -- this controls
220 the device. However, multiple Jobs (defined by a JCR structure src/jcr.h)
221 can be writing a physical DEVICE at the same time (of course they are
222 sequenced by locking the DEVICE structure). There are a lot of job
223 dependent "device" variables that may be different for each Job such as
224 spooling (one job may spool and another may not, and when a job is
225 spooling, it must have an i/o packet open, each job has its own record and
226 block structures, ...), so there is a device control record or DCR that is
227 the primary way of interfacing to the physical device. The DCR contains
228 all the job specific data as well as a pointer to the Device resource
229 (DEVRES structure) and the physical DEVICE structure.
231 Now if a job is writing to two devices (it could be writing two separate
232 streams to the same device), it must have two DCRs. Today, the code only
233 permits one. This won't be hard to change, but it is new code.
235 Today three jobs (threads), two physical devices each job
236 writes to only one device:
239 Job1 -> DCR1 -> DEVICE1
240 Job2 -> DCR2 -> DEVICE1
241 Job3 -> DCR3 -> DEVICE2
244 To be implemented three jobs, three physical devices, but
245 job1 is writing simultaneously to three devices:
248 Job1 -> DCR1 -> DEVICE1
251 Job2 -> DCR2 -> DEVICE1
252 Job3 -> DCR3 -> DEVICE2
254 Job = job control record
255 DCR = Job contorl data for a specific device
256 DEVICE = Device only control data