summaryrefslogtreecommitdiff
path: root/doc/upgrades+errors.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/upgrades+errors.txt')
-rw-r--r--doc/upgrades+errors.txt220
1 files changed, 220 insertions, 0 deletions
diff --git a/doc/upgrades+errors.txt b/doc/upgrades+errors.txt
new file mode 100644
index 000000000..09b5bd5ee
--- /dev/null
+++ b/doc/upgrades+errors.txt
@@ -0,0 +1,220 @@
+From ian Wed Nov 16 15:12:56 1994
+X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
+ [nil "Wed" "16" "November" "1994" "15:12:56" nil "ian" "ian" "" nil "dpkg - upgrades and error handling, take 2" "^To:" nil nil "11" nil nil nil nil]
+ nil)
+To: Debian dpkg list <debian-dpkg@pixar.com>
+Subject: dpkg - upgrades and error handling, take 2
+
+Here is a revised scheme for upgrade procedure and error handling.
+
+If you can see any serious problems with this please say so; if there
+are no compelling reasons not to I intend to implement the following.
+
+
+Procedure for new unpack:
+ * Run the preinst script (argument: `install').
+ * Back up the conffiles.
+ * Unpack the files in the package.
+This leaves the package in the `unpacked but not configured'
+state.
+
+If the preinst fails the installation is aborted immediately, leaving
+the package in whatever state it was originally. The preinst should
+clean up after its own failure.
+
+If the conffiles can't be backed up then any which have been are
+restored to their original names, if possible, and the postrm script
+is run if there is one (argument: `abort-install'). This leaves the
+package in its original state.
+
+If the unpack fails any files already unpacked are removed, the
+conffiles are restored to their original names, and the postrm is run
+(argument: `abort-install'). Again, the package remains in its
+original state.
+
+Errors found when running the postrm are ignored.
+
+
+Procedure for configuration:
+ * Do the conffile updating, including prompting, as in the spec.
+ * Run the postinst (argument: `configure').
+
+If the conffile updating fails anything that has been done is undone
+if possible and the package is left in the `unpacked but not
+configured' state.
+
+If the postinst fails dpkg gives up and leaves the package in the
+`postinst failed' state. Next time it will just rerun the
+postinst; if the postinst has a bug a new *.deb can be provided. In
+that case installation of the new *.deb will proceed almost as if it
+were a normal upgrade.
+
+
+Procedure for removal:
+ * Run the prerm (argument: `remove').
+ * Delete the files in the package and any resulting empty
+ directories.
+ * Run the postrm (argument: `remove').
+
+If the prerm fails dpkg leaves the package in the original state; if
+the user asks again to remove the package the prerm will be run again.
+
+If the deletion fails the removal is aborted, and the package left in
+the `removal failed' state.
+
+If the postrm fails dpkg leaves the package in the `removal failed'
+state.
+
+If the package is in the `removal failed' state to start with it will
+start again with deleting the files and empty directories and rerun
+the postrm.
+
+If the postrm has a bug a new *.deb must be installed first (using the
+upgrade procedure) and then removed. This is so that a working postrm
+script is provided.
+
+
+Procedure for upgrade:
+ * Run the old prerm script (arguments: `upgrade <new-version>').
+ * Move aside all existing files (not directories) for the
+ package being overwritten.
+ * Run the old postrm script (arguments: `upgrade <new-version>').
+ * Run the new preinst script (arguments: `upgrade <old-version>').
+ * Back up the conffiles.
+ * Unpack the files in the package.
+ * Remove the files which were moved aside.
+This leaves the package in the `unpacked but not configured'
+state.
+
+Errors during the removal of the files which were moved aside are
+flagged, but don't cause dpkg to attempt to abort the upgrade.
+
+If the old prerm or postrm script fails the corresponding script from
+the new package is run instead (arguments: `failed-upgrade
+<old-version>'). If there is no corresponding script in the new
+package the error is ignored.
+
+If any other stage fails, or if we try to use the script in the new
+package because the old prerm/postrm script failed but the new script
+fails too, we attempt to undo everything in reverse order, as follows:
+
+Unpacking the files in the package is undone by removing the files we
+unpacked and any empty directories, in reverse order. Errors are
+ignored.
+
+The conffiles backup is undone as much as possible, ignoring errors.
+
+The new preinst is undone by running the new postrm (arguments:
+`abort-upgrade <old-version>'); errors are ignored.
+
+The old postrm is undone by running the old preinst (arguments:
+`abort-upgrade <new-version>'); errors are ignored.
+
+Files we backed up are restored if possible; errors here leave the
+package in the `removal failed' state.
+
+The old prerm is undone by running the old postinst (arguments:
+`abort-upgrade <new-version>'). Errors here leave the package in the
+`postinst failed' state.
+
+
+Ian.
+
+From ian Wed May 17 02:14:09 +0100 1995
+X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
+ [nil nil nil nil nil nil nil nil nil nil nil nil "^To:" nil nil nil nil nil nil nil]
+ nil)
+To: Debian developers list <debian-devel@pixar.com>
+Subject: New dpkg overwriting handling
+
+Here is a comment that describes how I plan to have the new C dpkg act
+with respect to overwriting, upgrades, &c.
+
+The sequence of events during upgrade will change, because the removal
+of the old package and the installation of the new will take place
+together. So we have,
+
+ (noninteractive, during `dpkg --unpack' ...)
+ old prerm
+ new preinst
+ unpack new archive, possibly overwriting old files
+ delete any files in the old but not the new package
+ old postrm
+ run `postrm disappear' for any vanished packages, then forget them
+
+ (interactive, during `dpkg --configure' ...)
+ conffile updates
+ new postinst
+
+Furthermore, conffiles will not be backed up before unpack and have
+the user's old version hang around as `.dpkg-tmp'; instead, the old
+file will be left in place and the new one extracted into `.dpkg-new'.
+It will only be installed (if desired) at a conffile update.
+
+Thanks to Bruce for providing nice tar-in-a-function code that will
+allow me to handle each file individually rather than having tar splat
+them all out (and often do it buggily anyway).
+
+Ian.
+
+ /*
+ * Now we unpack the archive, backing things up as we go.
+ * For each file, we check to see if it already exists.
+ * There are several possibilities:
+ * + We are trying to install a non-directory ...
+ * - It doesn't exist. In this case we simply extract it.
+ * - It is a plain file, device, symlink, &c. We do an `atomic
+ * overwrite' using link() and rename(), but leave a backup copy.
+ * Later, when we delete the backup, we remove it from any other
+ * packages' lists.
+ * - It is a directory. We move it aside and extract the file.
+ * Later, when we delete the backed-up directory, we remove it
+ * from any other packages' lists.
+ * + We are trying to install a directory ...
+ * - It doesn't exist. We create it with the appropriate modes.
+ * - It is a plain file or a symlink. We move it aside and create
+ * the directory. Later, when we delete the backup, we remove it
+ * from any other packages' lists.
+ * - It exists as a directory. We do nothing.
+ *
+ * Install non-dir Install dir
+ * Exists not X C
+ * File/node/symlink LXR BCR
+ * Directory BXR -
+ *
+ * C: create directory
+ * X: extract file/node/link
+ * LX: atomic overwrite leaving backup
+ * B: ordinary backup
+ * R: later remove from other packages' lists
+ * -: do nothing
+ *
+ * After we've done this we go through the remaining things in the
+ * lists of packages we're trying to remove (including the old
+ * version of the current package). This happens in reverse order,
+ * so that we process files before the directories (or symlinks-to-
+ * directories) containing them.
+ * + If the thing is a conffile then we leave it alone for the purge
+ * operation.
+ * + Otherwise, there are several possibilities too:
+ * - The listed thing does not exist. We ignore it.
+ * - The listed thing is a directory or a symlink to a directory.
+ * We delete it only if it isn't listed in any other package.
+ * - The listed thing is not a directory or a symlink to one (ie,
+ * it's a plain file, device, pipe, &c, or a symlink to one, or a
+ * dangling symlink). We delete it.
+ * The removed packages' list becomes empty (of course, the new
+ * version of the package we're installing will have a new list,
+ * which replaces the old version's list).
+ *
+ * If at any stage we remove a file from a package's list, and the
+ * package isn't one we're already processing, and the package's
+ * list becomes empty as a result, we `vanish' the package. This
+ * means that we run its postrm with the `disappear' argument, and
+ * put the package in the `not-installed' state. Its conffiles are
+ * ignored and forgotten about.
+ *
+ * NOTE THAT THE OLD POSTRM IS RUN AFTER THE NEW PREINST, since the
+ * files get replaced `as we go'.
+ */
+