[dragonfly.git] / share / man / man7 / development.7
1 .\" Copyright (c) 1998 Matthew Dillon.  Terms and conditions are those of
2 .\" the BSD Copyright as specified in the file "/usr/src/COPYRIGHT" in
3 .\" the DragonFly source tree.
4 .\"
5 .\" $FreeBSD: src/share/man/man7/development.7,v 2003/05/23 07:48:35 brueffer Exp $
6 .\" $DragonFly: src/share/man/man7/development.7,v 1.12 2008/07/27 22:23:42 thomas Exp $
7 .\"
8 .Dd December 15, 2007
10 .Os
11 .Sh NAME
12 .Nm development
13 .Nd introduction to development with the DragonFly codebase
15 This manual page describes how an ordinary sysop,
16 .Ux admin, or developer
17 can, without any special permission, obtain, maintain, and modify the
18 .Dx
19 codebase as well as how to maintaining a master build which can
20 then be exported to other machines in your network.
21 This manual page
22 is targeted to system operators, programmers, and developers.
23 .Pp
24 Please note that what is being described here is based on a complete
25 .Dx
26 environment, not just the
27 .Dx
28 kernel.
29 The methods described
30 here are as applicable to production installations as it is to development
31 environments.
32 You need a good 12-17GB of disk space on one machine to make this work
33 conveniently.
35 Your master server should always run a stable, production version of the
36 .Dx
37 operating system.
38 This does not prevent you from doing -PREVIEW or -DEVELOPMENT
39 builds or development.
40 The last thing you want to do is to run an
41 unstable environment on your master server which could lead to a situation
42 where you lose the environment and/or cannot recover from a mistake.
43 .Pp
44 Create a partition called
45 .Pa /DragonFly .
46 8-12GB is recommended.
47 This partition will contain nearly all the development environment,
48 including the CVS tree, broken-out source, and possibly even object files.
49 You are going to export this partition to your other machines via a
50 .Sy read-only
51 NFS export so do not mix it with other more security-sensitive
52 partitions.
53 .Pp
54 You have to make a choice in regards to
55 .Pa /usr/obj .
56 You can put
57 .Pa /usr/obj
58 in
59 .Pa /DragonFly
60 or you can make
61 .Pa /usr/obj
62 its own partition.
63 I recommend making it a separate partition for several reasons.
64 First,
65 as a safety measure since this partition is written to a great deal.
66 Second, because you typically do not have to back it up.
67 Third, because it makes it far easier to mix and match the development
68 environments which are described later in this document.
69 I recommend a
70 .Pa /usr/obj
71 partition of at least 5GB.
72 .Pp
73 On the master server, use cvsup to automatically pull down and maintain
74 the
75 .Dx
76 CVS archive once a day.
77 The first pull will take a long time,
78 it is several gigabytes, but once you have it the daily syncs will be quite
79 small.
80 .Bd -literal -offset 4n
81 mkdir /DragonFly/DragonFly-CVS
82 rm -rf /home/dcvs
83 ln -s /DragonFly/DragonFly-CVS /home/dcvs
84 .Ed
85 .Pp
86 The cron job should look something like this (please randomize the time of
87 day!).
88 Note that you can use the cvsup file example directly from
89 .Pa /usr/share/examples
90 without modification by supplying appropriate arguments
91 to cvsup. Please use a cvsup mirror, see the
92 .Dx
93 site.
94 .Bd -literal -offset 4n
95 33 6 * * * /usr/local/bin/cvsup -gr 20 -L 2 -h \\
96   /usr/share/examples/cvsup/DragonFly-cvs-supfile
97 .Ed
98 .Pp
99 Run the cvsup manually the first time to pull down the archive.
100 It could take
101 all day depending on how fast your connection is!
102 You will run all cvsup and cvs operations as root and you need to set
103 up a
104 .Pa ~/.cvsrc
105 .Pa ( /root/.cvsrc )
106 file, as shown below, for proper cvs operation.
107 Using
108 .Pa ~/.cvsrc
109 to specify cvs defaults is an excellent way
110 to "file and forget", but you should never forget that you put them in there.
111 .Bd -literal -offset 4n
112 # cvs -q
113 diff -u
114 update -Pd
115 checkout -P
116 .Ed
117 .Pp
118 Now use cvs to checkout a -RELEASE source tree and a -DEVELOPMENT source tree,
119 as well as docs, to create your initial source environment.
120 Keeping the broken-out source in
121 .Pa /DragonFly
122 allows you to export
123 it to other machines via read-only NFS.
124 This also means you only need to edit/maintain files in one place and all
125 your clients automatically pick up the changes.
126 .Bd -literal -offset 4n
127 mkdir /DragonFly/DragonFly-RELEASE
128 mkdir /DragonFly/DragonFly-DEVELOPMENT
130 cd /DragonFly/DragonFly-RELEASE
131 cvs -d /home/dcvs checkout -r DragonFly_RELEASE_1_10_Slip src
133 cd /DragonFly/DragonFly-DEVELOPMENT
134 cvs -d /home/dcvs checkout src
135 cvs -d /home/dcvs checkout doc
136 .Ed
137 .Pp
138 Now create a softlink for
139 .Pa /usr/src
140 and
141 .Pa /usr/src2 .
142 On the main server I always point
143 .Pa /usr/src
144 at -RELEASE and
145 .Pa /usr/src2
146 at
148 On client machines I usually do not have a
149 .Pa /usr/src2
150 and I make
151 .Pa /usr/src
152 point at whatever version of
153 .Dx
154 the client box is intended to
155 run.
156 .Bd -literal -offset 4n
157 cd /usr
158 rm -rf src src2
159 ln -s /DragonFly/DragonFly-RELEASE/src src      (could be -DEVELOPMENT on a client)
160 ln -s /DragonFly/DragonFly-DEVELOPMENT/src src2 (MASTER SERVER ONLY)
161 .Ed
162 .Pp
163 Now you have to make a choice for
164 .Pa /usr/obj .
165 Well, hopefully you made it already and chose the partition method.
166 If you
167 chose poorly you probably intend to put it in
168 .Pa /DragonFly
169 and, if so, this is
170 what you want to do:
171 .Bd -literal -offset 4n
172 (ONLY IF YOU MADE A POOR CHOICE AND PUT /usr/obj in /DragonFly!)
173 mkdir /DragonFly/obj
174 cd /usr
175 rm -rf obj
176 ln -s /DragonFly/obj obj
177 .Ed
178 .Pp
179 Alternatively you may chose simply to leave
180 .Pa /usr/obj
181 in
182 .Pa /usr .
183 If your
184 .Pa /usr
185 is large enough this will work, but I do not recommend it for
186 safety reasons
187 .Pa ( /usr/obj
188 is constantly being modified,
189 .Pa /usr
190 is not).
191 .Pp
192 Note that exporting
193 .Pa /usr/obj
194 via read-only NFS to your other boxes will
195 allow you to build on your main server and install from your other boxes.
196 If you also want to do builds on some or all of the clients you can simply
197 have
198 .Pa /usr/obj
199 be a local directory on those clients.
200 You should never export
201 .Pa /usr/obj
202 read-write, it will lead to all sorts of
203 problems and issues down the line and presents a security problem as well.
204 It is far easier to do builds on the master server and then only do installs
205 on the clients.
207 The master server needs to export
208 .Pa /DragonFly
209 and
210 .Pa /usr/obj
211 via NFS so all the
212 rest of your machines can get at them.
213 I strongly recommend using a read-only export for both security and safety.
214 The environment I am describing in this manual page is designed primarily
215 around read-only NFS exports.
216 Your
217 .Pa /etc/exports
218 file on the master server should contain the following lines:
219 .Bd -literal -offset 4n
220 /DragonFly -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
221 /usr/obj   -ro -alldirs -maproot=root: -network YOURLAN -mask YOURLANMASK
222 .Ed
223 .Pp
224 Of course, NFS server operations must also be configured on that machine.
225 This is typically done via your
226 .Pa /etc/rc.conf :
227 .Bd -literal -offset 4n
228 nfs_server_enable="YES"
229 .Ed
231 All of your client machines can import the development/build environment
232 directory simply by NFS mounting
233 .Pa /DragonFly
234 and
235 .Pa /usr/obj
236 from the master
237 server.
238 A typical
239 .Pa /etc/fstab
240 entry on your client machines will be something like this:
241 .Bd -literal -offset 4n
242 masterserver:/DragonFly   /DragonFly      nfs     ro,bg    0       0
243 masterserver:/usr/obj     /usr/obj        nfs     ro,bg    0       0
244 .Ed
245 .Pp
246 And, of course, you should configure the client for NFS client operations
247 via
248 .Pa /etc/rc.conf .
249 In particular, this will turn on nfsiod which will improve client-side NFS
250 performance:
251 .Bd -literal -offset 4n
252 nfs_client_enable="YES"
253 .Ed
254 .Pp
255 Each client should create softlink for
256 .Pa /usr/src
257 that point
258 into the NFS-mounted environment.
259 If a particular client is running -DEVELOPMENT,
260 .Pa /usr/src
261 should be a softlink to
262 .Pa /DragonFly/DragonFly-DEVELOPMENT/src .
263 If it is running -RELEASE,
264 .Pa /usr/src
265 should be a softlink to
266 .Pa /DragonFly/DragonFly-RELEASE/src .
267 I do not usually create a
268 .Pa /usr/src2
269 softlink on
270 clients, that is used as a convenient shortcut when working on the source
271 code on the master server only and could create massive confusion (of the
272 human variety) on a client.
273 .Bd -literal -offset 4n
275 cd /usr
276 ln -s /DragonFly/DragonFly-XXX/src src
277 .Ed
279 Here is how you build a -RELEASE kernel (on your main development box).
280 If you want to create a custom kernel, copy
282 to
284 and then
285 edit it before configuring and building.
286 The kernel configuration file lives in
287 .Pa /sys/config/KERNELNAME .
288 .Bd -literal -offset 4n
289 cd /usr/src
290 make buildkernel KERNCONF=KERNELNAME
291 .Ed
292 .Pp
293 Building a -DEVELOPMENT kernel
294 .Bd -literal -offset 4n
295 cd /usr/src2            (on the master server)
296 make buildkernel KERNCONF=KERNELNAME
297 .Ed
299 Installing a -RELEASE kernel (typically done on a client.
300 Only do this on your main development server if you want to install a new
301 kernel for your main development server):
302 .Bd -literal -offset 4n
303 cd /usr/src
304 make installkernel KERNCONF=KERNELNAME
305 .Ed
306 .Pp
307 Installing a -DEVELOPMENT kernel (typically done only on a client)
308 .Bd -literal -offset 4n
309 (remember /usr/src is pointing to the client's specific environment)
310 cd /usr/src
311 make installkernel KERNCONF=KERNELNAME
312 .Ed
314 This environment is designed such that you do all builds on the master server,
315 and then install from each client.
316 You can do builds on a client only if
317 .Pa /usr/obj
318 is local to that client.
319 Building the world is easy:
320 .Bd -literal -offset 4n
321 cd /usr/src
322 make buildworld
323 .Ed
324 .Pp
325 If you are on the master server you are running in a -RELEASE environment, but
326 that does not prevent you from building the -DEVELOPMENT world.
327 Just cd into the appropriate source directory and you are set.
328 Do not
329 accidentally install it on your master server though!
330 .Bd -literal -offset 4n
331 cd /usr/src2
332 make buildworld
333 .Ed
335 You can build on your main development server and install on clients.
336 The main development server must export
337 .Pa /DragonFly
338 and
339 .Pa /usr/obj
340 via
341 read-only NFS to the clients.
342 .Pp
343 .Em NOTE!!!
344 If
345 .Pa /usr/obj
346 is a softlink on the master server, it must also be the EXACT
347 SAME softlink on each client.
348 If
349 .Pa /usr/obj
350 is a directory in
351 .Pa /usr
352 or a mount point on the master server,
353 then it must be (interchangeably) a directory in
354 .Pa /usr
355 or a mount point on
356 each client.
357 This is because the
358 absolute paths are expected to be the same when building the world as when
359 installing it, and you generally build it on your main development box
360 and install it from a client.
361 If you do not setup
362 .Pa /usr/obj
363 properly you will not be able to build on
364 machine and install on another.
365 .Bd -literal -offset 4n
367 (remember
368 .Pa /usr/src
369 is pointing to the client's specific environment)
370 cd /usr/src
371 make installworld
372 .Ed
373 .Pp
374 .Sy WARNING!
375 If builds work on the master server but installs do not work from the
376 clients, for example you try to install and the client complains that
377 the install tried to write into the read-only
378 .Pa /usr/obj ,
379 then it is likely
380 that the
381 .Pa /etc/make.conf
382 file on the client does not match the one on the
383 master server closely enough and the install is trying to install something
384 that was not built.
386 Developers often want to run buildkernel's or buildworld's on client
387 boxes simply to life-test the box.
388 You do this in the same manner that you buildkernel and buildworld on your
389 master server.
390 All you have to do is make sure that
391 .Pa /usr/obj
392 is pointing to local storage.
393 If you followed my advise and made
394 .Pa /usr/obj
395 its own partition on the master
396 server,
397 then it is typically going to be an NFS mount on the client.
398 Simply unmounting
399 .Pa /usr/obj
400 will leave you with a
401 .Pa /usr/obj
402 that is a
403 subdirectory in
404 .Pa /usr
405 which is typically local to the client.
406 You can then do builds to your heart's content!
408 I have described how to maintain two versions of the source tree, a stable
409 version in
410 .Pa /DragonFly/DragonFly-RELEASE
411 and a current version
412 in
413 .Pa /DragonFly/DragonFly-DEVELOPMENT .
414 There is absolutely nothing preventing you
415 from breaking out other versions of the source tree
416 into
417 .Pa /DragonFly/XXX .
418 In fact, my
419 .Pa /DragonFly
420 partition also contains
421 .Fx ,
422 .Ox ,
423 .Nx ,
424 and various flavors of Linux.
425 You may not necessarily be able to build
426 .Pf non- Dx
427 operating systems on your master server, but being able
428 to collect and manage source distributions from a central server is a very
429 useful thing to be able to do and you can certainly export to machines
430 which can build those other operating systems.
431 .Pp
432 Many developers choose to maintain a local branch of
433 .Dx
434 to test patches or build a custom distribution.
435 This can be done with CVS or another source code management system
436 (SubVersion, Perforce, BitKeeper) with its own repository.
437 Since the main
438 .Dx
439 tree is based on CVS, the former is convenient.
440 .Pp
441 First, you need to modify your cvsup environment to avoid it modifying
442 the local changes you have committed to the repository.
443 It is important to remove the "delete" keyword from your supfile and to
444 add the CVSROOT subdirectory to your refuse file.
445 For more information, see
446 .Xr cvsup 1 .
447 .Pp
448 The
449 .Dx
450 version of CVS examines a custom environmental variable,
451 CVS_LOCAL_BRANCH_NUM, which specifies an integer to use when doing a cvs
452 tag/rtag.
453 Set this number to something high (say 1000) to avoid colliding
454 with potential future branches of the main repository.
455 For example,
456 branching a file with version 1.4 produces 1.4.1000.
457 Future commits to this branch will produce revisions 1.4.1000.1,
458 1.4.1000.2, etc.
459 .Pp
460 To fork your local branch, do:
461 .Bd -literal -offset 4n
462 cvs rtag -r DragonFly_RELEASE_1_10_Slip -b LOCAL_DragonFly_RELEASE_1_10 src
463 .Ed
464 .Pp
465 After this, you can check out a copy from your local repository using the
466 new tag and begin making changes and committing them.
467 For more information on using cvs, see
468 .Xr cvs 1 .
469 .Pp
470 .Sy WARNING!
471 The cvsup utility may blow away changes made on a local branch in
472 some situations.
473 This has been reported to occur when the master CVS repository is
474 directly manipulated or an RCS file is changed.
475 At this point, cvsup notices that the client and server have entirely
476 different RCS files, so it does a full replace instead of trying to
477 send just deltas.
478 Ideally this situation should never arise, but in the real world it
479 happens all the time.
480 .Pp
481 While this is the only scenario where the problem should crop up,
482 there have been some suspicious-sounding reports of
483 CVS_LOCAL_BRANCH_NUM lossage that can't be explained by this alone.
484 Bottom line is, if you value your local branch then you
485 should back it up before every update.
487 The advantage of using cvsup to maintain an updated copy of the CVS
488 repository instead of using it to maintain source trees directly is that you
489 can then pick and choose when you bring your source tree (or pieces of your
490 source tree) up to date.
491 By using a cron job to maintain an updated CVS repository, you can update
492 your source tree at any time without any network cost as follows:
493 .Bd -literal -offset 4n
494 (on the main development server)
495 cd /usr/src
496 cvs -d /home/dcvs update
497 cd /usr/src2
498 cvs -d /home/dcvs update
499 .Ed
500 .Pp
501 It is that simple, and since you are exporting the whole lot to your
502 clients, your clients have immediately visibility into the updated
503 source.
504 This is a good time to also remind you that most of the cvs operations
505 you do will be done as root, and that certain options are
506 required for CVS to operate properly on the
507 .Dx
508 repository.
509 For example,
510 .Fl Pd
511 is necessary when running "cvs update".
512 These options are typically placed in your
513 .Pa ~/.cvsrc
514 (as already described)
515 so you do not have to respecify them every time you run a CVS command.
516 Maintaining the CVS repository also gives you far more flexibility
517 in regards to breaking out multiple versions of the source tree.
518 It is a good idea to give your
519 .Pa /DragonFly
520 partition a lot of space (I recommend
521 8-12GB) precisely for that reason.
522 If you can make it 15GB I would do it.
523 .Pp
524 I generally do not cvs update via a cron job.
525 This is because I generally want the source to not change out from under me
526 when I am developing code.
527 Instead I manually update the source every so often...\& when I feel it is
528 a good time.
529 My recommendation is to only keep the cvs repository synchronized via cron.
530 .Sh SEE ALSO
531 .Xr crontab 1 ,
532 .Xr cvs 1 ,
533 .Xr cvsup 1 ,
534 .Xr crontab 5 ,
535 .Xr exports 5 ,
536 .Xr kernconf 5 ,
537 .Xr make.conf 5 ,
538 .Xr build 7 ,
539 .Xr committer 7 ,
540 .Xr firewall 7 ,
541 .Xr release 7 ,
542 .Xr tuning 7 ,
543 .Xr diskless 8
545 The
546 .Nm
547 manual page was originally written by
548 .An Matthew Dillon Aq
549 and first appeared
550 in
551 .Fx 5.0 ,
552 December 2002.