Hey Raphael

On Tue, Aug 16, 2011 at 10:11:03PM +0200, Raphael Hertzog wrote:
> Hi Salvatore,
> 
> On Tue, 16 Aug 2011, Salvatore Bonaccorso wrote:
> > Attached is a tentative patch trying to solve this: a link should only
> > be updated, if it does not point to the right place.
> 
> Can you add a test-case for this? I guess that verifying that the inode
> number did not change is a good way to verify that the link did not get
> replaced... see utils/t/100_update_alternatives.t.

Yes, but I still need to do that.

But attached is an updated version for the patch, is this better
suitable so far? Jan, changed the parts you mentioned.

Regards
Salvatore
From b432597c512aa780c72d40403c607fdc829a1e3b Mon Sep 17 00:00:00 2001
From: Salvatore Bonaccorso <car...@debian.org>
Date: Fri, 26 Aug 2011 08:30:28 +0200
Subject: [PATCH] Update altenrative links only if needed

Update the alternatives symlinks only if needed. In case the link
already point to the correct location, update-alternatives don't update
the symlink. This is helpfull if e.g. /usr is mountet read-only and the
links there are not affected by an update-alternatives change but only
links in writable part (e.g. /etc/alternatives).

Closes: #636700
---
 utils/update-alternatives.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/utils/update-alternatives.c b/utils/update-alternatives.c
index 8e82bb6..6d1fade 100644
--- a/utils/update-alternatives.c
+++ b/utils/update-alternatives.c
@@ -1651,6 +1651,26 @@ alternative_can_replace_path(const char *linkname)
 	return replace_link;
 }
 
+static bool
+alternative_link_needs_update(const char *linkname, const char *target)
+{
+	char *lntarget;
+	bool update_needed = true;
+	struct stat st;
+
+	if (lstat(linkname, &st) == 0) {
+		if (S_ISLNK(st.st_mode)) {
+			lntarget = xreadlink(linkname, false);
+			if (strcmp(target, lntarget) == 0) {
+				update_needed = false;
+			}
+			free(lntarget);
+		}
+	}
+
+	return update_needed;
+}
+
 static void
 alternative_prepare_install_single(struct alternative *a, const char *name,
 				   const char *linkname, const char *file)
@@ -1665,7 +1685,9 @@ alternative_prepare_install_single(struct alternative *a, const char *name,
 	alternative_add_commit_op(a, opcode_mv, fntmp, fn);
 	free(fntmp);
 
-	if (alternative_can_replace_path(linkname)) {
+	if (!alternative_link_needs_update(linkname,fn)) {
+		/* Link already correct, no update required */
+	} else if (alternative_can_replace_path(linkname)) {
 		/* Create alternative link. */
 		xasprintf(&fntmp, "%s" DPKG_TMP_EXT, linkname);
 		checked_rm(fntmp);
-- 
1.7.5.4

Attachment: signature.asc
Description: Digital signature

Reply via email to