fwcf.txt 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1.  FreeWRT Configuration Filesystem
  2. ════════════════════════════════
  3. Specification Document
  4. Version 1.04 - 2 July 2007
  5. Copyright © 2006, 2007
  6. Thorsten Glaser <tg@mirbsd.de>
  7. Provided that these terms and disclaimer and all copyright notices
  8. are retained or reproduced in an accompanying document, permission
  9. is granted to deal in this work without restriction, including un-
  10. limited rights to use, publicly perform, distribute, sell, modify,
  11. merge, give away, or sublicence.
  12. Advertising materials mentioning features or use of this work must
  13. display the following acknowledgement:
  14. This product includes material provided by Thorsten Glaser
  15. for the FreeWRT Project.
  16. This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
  17. the utmost extent permitted by applicable law, neither express nor
  18. implied; without malicious intent or gross negligence. In no event
  19. may a licensor, author or contributor be held liable for indirect,
  20. direct, other damage, loss, or other issues arising in any way out
  21. of dealing in the work, even if advised of the possibility of such
  22. damage or existence of a defect, except proven that it results out
  23. of said person's immediate fault when using the work as intended.
  24. 1. Abstract
  25. ―――――――――――
  26. FreeWRT is an operating system for embedded devices. At the moment,
  27. it provides a uClibc/GNU/Linux-based operating environment for mips-
  28. based hardware routers, e.g. from Linksys or Asus.
  29. FreeWRT operates on flash memory and as such is under constraints to
  30. reduce the amount of write operations to the root filesystem, because
  31. flash memory has limited lifetime. Changing the file-based configura-
  32. tion in /etc, however, often requires a fair amount of write opera-
  33. tions; furthermore, usual reconfiguration operations change more than
  34. only one file, possibly erasing and re-writing the same flash memory
  35. block several times. In addition, in between these changes, the sy-
  36. stem is in an inconsistent state, and, if the configuration changes
  37. render the system unusable, a simple reboot will not be able to fix
  38. it, a full reflash and reconfiguration is required.
  39. My proposed implementation will present /etc as a memory filesystem,
  40. loaded at boot with the content of the underlying /etc from the de-
  41. fault root filesystem (usually on squashfs or jffs2), then populated
  42. with additional files read from a custom flash partition in the be-
  43. low documented format. Changes to /etc will never be reflected in the
  44. underlying root filesystem, and the fwcf partition is only updated by
  45. a userland programme to be run manually.
  46. 2. Implementation details
  47. ―――――――――――――――――――――――――
  48. The size of the flash partition has been set by the FreeWRT project
  49. to 128 KiB (usually two flash blocks). A custom flash map driver has
  50. been added to the FreeWRT kernel before the import of fwcf.
  51. The command-line utility will support three operations:
  52. • fwcf setup to be run by the rc bootup script early
  53. • fwcf commit similar to Cisco ‘write’
  54. • fwcf erase similar to Cisco ‘erase startup-config’
  55. • fwcf status NEW IN 1.03: check if commit is needed
  56. • fwcf dump NEW IN 1.03: make a backup of the fwcf filesystem
  57. • fwcf restore NEW IN 1.03: restore a previously made backup
  58. • halt \
  59. • poweroff > NEW IN 1.04: wrapper around busybox
  60. • reboot /
  61. This utility is implemented as rapid prototype as a shell script in
  62. ash, using one C helper programme. Later versions will be pure C.
  63. 2.1. Operation of ‘fwcf setup’
  64. ――――――――――――――――――――――――――――――
  65. This command will first remap the existing /etc (via ‘mount --bind’)
  66. to /tmp/.fwcf/root. Then, it will create a memory filesystem (tmpfs)
  67. at /tmp/.fwcf/temp and populate it with all files from /tmp/.fwcf/root.
  68. Now, the fwcf flash partition will be read, the format and checksum
  69. verified and data extracted to /tmp/.fwcf/temp, possibly overwriting
  70. pre-existing files†. Then, the /tmp/.fwcf/temp filesystem will be re-
  71. bound to /etc and, finally, the mountpoint at /tmp/.fwcf/temp unloaded.
  72. NEW IN 1.03: If /etc/.fwcf_deleted exists, the files listed in it,
  73. newline-separated, will be removed from and relative to /etc, then
  74. the file itself will be removed.
  75. Data from the end of the fwcf data in the flash partition to the
  76. end of the 64 KiB block the end of data resides in will be written
  77. to /dev/urandom.
  78. NEW IN 1.03: Afterwards, a sorted list of all files is given to the
  79. busybox md5sum applet, the output is stored as /tmp/.fwcf/status.asz
  80. If the “fwcf” mtd partition does not start with the four letters
  81. FWCF on invoking ‘fwcf setup’, it is erased (i.e. populated with
  82. an empty FWCF filesystem).
  83. NEW IN 1.03: If run with ‘-N’, it will not read out the data from
  84. flash and force an “unclean startup”, as described below.
  85. †) NEW IN 1.03: If this fails, but the “fwcf” mtd partition starts
  86. with FWCF, i.e. we cannot read the flash filesystem, possibly because
  87. it's from an incompatible format or unknown compressor, a flag file
  88. is created as /etc/.fwcf_unclean to prevent a following commit which
  89. would lead to data loss. The user must remove this file to override.
  90. 2.2. Operation of ‘fwcf commit’
  91. ―――――――――――――――――――――――――――――――
  92. A new memory filesystem (tmpfs) will be createt at /tmp/.fwcf/temp
  93. and populated with the data currently in /etc. Now, NEW IN 1.03,
  94. the /tmp/.fwcf/status.asz file is recreated. Then, ALSO NEW IN 1.03,
  95. files in /tmp/.fwcf/root but not in /tmp/.fwcf/temp will be listed
  96. in /tmp/.fwcf/temp/.fwcf_deleted, newline-separated. Now, all files
  97. with exactly the same content in /tmp/.fwcf/root will be removed
  98. from /tmp/.fwcf/temp. Any remaining files will be packed into the
  99. fwcf format documented below and written to the flash partition,
  100. padded to a multiple of 64 KiB with data read from /dev/urandom.
  101. Unclean setups, NEW IN 1.03, will prevent a commit, unless the
  102. file /etc/.fwcf_unclean is removed manually, or the ‘-f’ option
  103. is given.
  104. The first public release does only support directories, files
  105. and symbolic links, for simplicity. Stored hard links and other
  106. file types will be skipped, because their storage format is al-
  107. ready specified (as “reserved for future use”), and ignored. No
  108. inode or file-sequential-number information is read or written.
  109. 2.3. Operation of ‘fwcf erase’
  110. ――――――――――――――――――――――――――――――
  111. In theory, just writing a NUL byte to the beginning of the flash
  112. partition would suffice. However, this requires an mtd erase and
  113. flash operation of one entire flash block (usually 64 KiB), so an
  114. empty fwcf filesystem padded with random data to the next 64 KiB
  115. will be written instead, for the added benefit of improving the
  116. quality of the kernel PRNG even over total reconfigurations.
  117. 2.4. Operation of ‘fwcf status’ (NEW IN 1.03)
  118. ――――――――――――――――――――――――――――――― ┄┄┄┄┄┄┄┄┄┄┄┄┄
  119. For all files in /etc, the ‘md5sum’ busybox applet is run, output
  120. stored in a temporary file and compared against the saved values
  121. from ‘fwcf setup’. If the ‘-q’ flag is not given, the differences
  122. are shown as “<oldmd5><space><newmd5><space><file>”, where the md5
  123. is expressed as shown by the busybox applet, or as padded¹ “<NULL>”
  124. if the file does not exist on either side, where “old” is the status
  125. at fwcf setup time (or the /etc from the root fs, if ‘-r’ is given),
  126. and “new” is the status of the current (tmpfs) /etc. If there are
  127. no differences, the exit status is 0, non-0 otherwise.
  128. If the ‘-r’ flag is given, operation is done against the data that
  129. is stored in the ROM, without considering the contents of the FWCF
  130. filesystem, instead.
  131. ¹) Every “MD5” value is padded to be 32 bytes long, at its left
  132. side, with spaces (just to clarify).
  133. 2.5. Operation of ‘fwcf dump’ (NEW IN 1.03)
  134. ――――――――――――――――――――――――――――― ┄┄┄┄┄┄┄┄┄┄┄┄┄
  135. A dump of the data currently stored in flash (commit first if you
  136. have changed anything!) is dumped to the filename argument, or to
  137. standard output, if none is present.
  138. Note: dumps are a LZO1X compressed tarball of a 256-byte entropy
  139. seed (“seed”) and the contents of the “inner filesystem” in “asz”
  140. format (“dump”), which is stored as .tar.asz itself. There is no
  141. version information, and this is by design.
  142. Implementation information: the fwcf helper tool has a new mo-
  143. de of operation in which it works as compressor/decompressor –
  144. the algorithm used is determined with the -C option on a build
  145. system, and at compile time (i.e. the only one compiled in) on
  146. the target system. That's a compromise relative to using gzip,
  147. because it makes dumps depend on the compression algorithms in
  148. use, but it's always LZO1X-1 in FreeWRT 1.03 and up, and no de-
  149. pendency on a 50+ KiB gzip binary is added; the .tar.asz enco-
  150. ded dump can be recompressed with the tool on the build system.
  151. While the dump itself is tar → compressed → asz encoded, “asz”
  152. itself is not a compressing format, just a storage container –
  153. which stores one octet stream, plus size and checksum informa-
  154. tion only. Because many compressors have no idea about the un-
  155. compressed size, the actual encoded data is prefixed by a lit-
  156. tle endian unsigned 32-bit integer of the uncompressed length;
  157. the resulting larger buffer is then passed to the asz encoder.
  158. 2.6. Operation of ‘fwcf restore’ (NEW IN 1.03)
  159. ―――――――――――――――――――――――――――――――― ┄┄┄┄┄┄┄┄┄┄┄┄┄
  160. A dump created with “fwcf dump” is expected to be read from the
  161. filename argument, or standard input, if none is present, and
  162. then written to flash.
  163. 3. Structure of the fwcf data
  164. ―――――――――――――――――――――――――――――
  165. All data is written in little-endian format.
  166. The fwcf data begins at offset 0 in the flash partition, with the
  167. magic bytes “FWCF” (0x46435746).
  168. The next doubleword (four bytes) is the “outer length” of the fwcf
  169. data, including the header (including the magic bytes and the length
  170. information itself) and the trailer (checksum), but not the padding;
  171. the length takes up the lower 24 bits of this doubleword. The upper
  172. 8 bits are the (major) version of the specification adhered to, i.e.
  173. 0x01 for this document. This information shall be true for all ver-
  174. sions of this specification in order to enable the fwcf command-line
  175. utility to perform as follows: it is not required to process any non-
  176. native versions of fwcf data, but even if reading a different version,
  177. the random data used for the padding should be written to /dev/urandom.
  178. The following information is dependent on the version of the speci-
  179. fication.
  180. The next doubleword (starting at offset 8) is the “inner length” of
  181. the compressed fwcf data (lower 24 bit), or'd with the identification
  182. number of the compression algorithm used (upper 8 bit). Note this ef-
  183. fectively limits both the uncompressed and the compressed size of an
  184. fwcf filesystem to 2²⁴ bytes = 16 MiB. Since the filesystem is de-
  185. signed for /etc, this limitation is not expected to be troublesome.
  186. After this, at offset 12, the compressed data starts. It is padded
  187. to the next 4-byte boundary with zeroes.
  188. The next doubleword is the ADLER-32 checksum (as defined by libz)
  189. of all previous data, starting from the magic bytes at offset 0,
  190. ending with the zero-padding of the compressed data. Note that this
  191. does not check the integrity of the data after decompressing; cur-
  192. rently we must trust the decompressor to check integrity and do a
  193. length check on the decompressed data returned by the plugin our-
  194. selves. The next major version of the specification may change that.
  195. 4. Compression algorithm allocation
  196. ―――――――――――――――――――――――――――――――――――
  197. An implementation is only required to be able to use exactly one of
  198. the compression algorithms defined below, but it is not required to
  199. implement a specific algorithm. Conversion might be achieved by un-
  200. and repacking the data, or using an fwcf implementation with multi-
  201. ple algorithms. Every implementation, however, is required to offer
  202. at least one of the non-private algorithms below.
  203. This draft of the specification offers two compression algorithms:
  204. 0x00 = plain uncompressed data
  205. 0x01 = zlib deflate compression as per http://www.zlib.net/
  206. 0x10 = LZO1X as per http://www.oberhumer.com/opensource/lzo/
  207. Algorithm codes from 0xE0 to 0xFF are available for private use.
  208. 5. Structure of the fwcf filesystem
  209. ―――――――――――――――――――――――――――――――――――
  210. The compressed/inner data consists of a byte stream without padding
  211. applied, in the following format:
  212. entry ::= file-entry | NUL-byte
  213. file-entry ::= pathname NUL-byte attributes NUL-byte data
  214. attributes ::= attribute ( attribute )*
  215. The pathname is a POSIX pathname, i.e. can contain any character
  216. except NUL. Directories are separated with ‘/’ and automatically
  217. created by the extraction tool if required. If the first octet
  218. of the pathname is a NUL byte (i.e. it is of zero length), the
  219. end of the filesystem has been reached. Any data read afterwards
  220. MUST be discarded for security reasons.
  221. Attributes consist of a one-byte identifier, which is usually a
  222. letter, and a zero-to-multiple-bytes payload. If the identifier
  223. is a letter, its lowercase and uppercase forms denote the same
  224. attribute with a different payload length.
  225. The raw file data is not padded or aligned; its length is an at-
  226. tribute. Alternate streams / forks are not supported.
  227. 6. Currently defined attributes
  228. ―――――――――――――――――――――――――――――――
  229. 0x01 this file is a block special device ①
  230. no payload
  231. reserved for future use
  232. 0x02 this file is a character special device ①
  233. no payload
  234. reserved for future use
  235. 0x03 this file is a symbolic link ②
  236. no payload
  237. 0x04 this file is a hard link to another file ① ④
  238. no payload
  239. reserved for future use
  240. 0x05 this file is a directory ④
  241. no payload
  242. 0x0D this file is deleted ①
  243. reserved for future use
  244. 0x10 modification time of the entry
  245. optional
  246. ignored for symbolic links
  247. payload length: 32 bit
  248. g/G group of the file (numeric GID)
  249. optional
  250. payload length: lowercase = 8 bit, uppercase = 32 bit
  251. i/I “inode” of the file ① ④
  252. required if this file is a hard link source or target
  253. optional (ignored) otherwise
  254. payload length: lowercase = 8 bit, uppercase = 16 bit
  255. reserved for future use
  256. m/M mode_t / permissions of the file ③
  257. optional
  258. ignored for symbolic links
  259. payload length: lowercase = 16 bit, uppercase = 32 bit
  260. o/O owner of the file (numeric UID)
  261. optional
  262. payload length: lowercase = 8 bit, uppercase = 32 bit
  263. s/S size of the file
  264. for files and symbolic links: mandatory
  265. for directories, device nodes and hard links: forbidden
  266. payload length: lowercase = 8 bit, uppercase = 24 bit
  267. ① These identifiers are defined in this specification for future
  268. use; implementations do not need to support them at this time.
  269. ② The name of the target is the data, thus, size is required.
  270. ③ Defaults to 0 if not used (for security reasons), so labelling
  271. it as “optional” is probably a farce ☺
  272. ④ Implementing hard links and directories is, of course, optional
  273. for the writer.
  274. 7. Miscellaneous
  275. ――――――――――――――――
  276. The initial idea for a “configuration filesystem” based upon the
  277. Linux FUSE kernel module has been communicated to me by Waldemar
  278. Brodkorb, FreeWRT Project Founder. After a discussion with him I
  279. decided on the archive/userland tool layout outlined in sections
  280. 1 and 2 above. For FreeWRT 1.0, it has been realised in shell.
  281. For now, nodes other than directories, files, and symbolic links
  282. are not supported.
  283. Development of FWCF is hosted in the CVS repository of the MirOS
  284. project. Anonymous read-only CVS access is available at the root
  285. “:ext:anoncvs@anoncvs.mirbsd.org:/cvs” using password “anoncvs”,
  286. SSH on port 22; module “fwcf”. CVSweb is also available, e.g. at
  287. http://cvs.mirbsd.de/contrib/hosted/fwcf/ or its mirrors.
  288. FWCF code is released under the same licence terms as the speci-
  289. fication, but without the advertising clause. The author however
  290. would really appreciate users to credit his name and that of the
  291. FreeWRT Project in derived works and/or links to the CVS reposi-
  292. tory of the original source.
  293. 8. The “asz” file format (NEW IN 1.03)
  294. ―――――――――――――――――――――――― ┄┄┄┄┄┄┄┄┄┄┄┄┄
  295. The “asz” format is intended for storing small arbitrary 8-bit
  296. data, and used in the “fwcf dump” and “fwcf restore” formats –
  297. the dump itself is a raw uncompressed “inner fwcf filesystem”,
  298. stored as “asz”, and the storage used by the dump/restore com-
  299. mands is a tarball, compressed with lzo1X1 (in the current im-
  300. plementation), the result stored, again, as “asz”.
  301. It almost looks like the “outer fwcf” format, except the start
  302. isn't a header but the ADLER-32 checksum double-word (2 unsig-
  303. ned 16-bit integer in LITTLE ENDIAN), i.e. without magic bytes
  304. to identify the format; followed by the length double-word – 1
  305. unsigned 32-bit integer in LITTLE ENDIAN – and finally the raw
  306. binary data. Only the lowest three octets of the length should
  307. be used because the current implementation malloc(3)s a buffer
  308. containing the whole data.
  309. 9. Future directions
  310. ――――――――――――――――――――
  311. The next major version of the FWCF filesystem specification is
  312. likely to contain the following changes:
  313. • An additional checksum (probably ADLER32 as well) shall be
  314. placed inside the compressed portion, to be checked after
  315. decompression. The idea of adding a random IV has not been
  316. adopted because we pretty much want the same FWCF blocks,
  317. except the random padding at the end, to be generated for
  318. the same input data. (This is not guaranteed because fts()
  319. may traverse the directory hierarchy differently.)
  320. • Revisit the current size limits and file types.
  321. • Implement a r̲e̲a̲l̲ file type “deleted”, replacing the hack
  322. with the .fwcf_deleted file.
  323. These future directions have come up during or after the
  324. fwcf 1.00 release process, and from the discussion thereafter.
  325. They are provided as hint only and not part of the specifi-
  326. cation itself. They may change without notice.
  327. ⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼
  328. $MirOS: contrib/hosted/fwcf/fwcf.txt,v 1.37 2007/07/02 14:55:44 tg Exp $