diff --git a/addnote.c b/addnote.c new file mode 100644 index 0000000..d2be416 --- /dev/null +++ b/addnote.c @@ -0,0 +1,205 @@ +/* + * Program to hack in a PT_NOTE program header entry in an ELF file. + * This is needed for OF on RS/6000s to load an image correctly. + * Note that OF needs a program header entry for the note, not an + * ELF section. + * + * Copyright 2000 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Usage: addnote zImage + */ +#include +#include +#include +#include +#include + +/* CHRP note section */ +char arch[] = "PowerPC"; + +#define N_DESCR 6 +unsigned int descr[N_DESCR] = { + 0xffffffff, /* real-mode = true */ + 0x02000000, /* real-base, i.e. where we expect OF to be */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x4000, /* load-base */ +}; + +/* RPA note section */ +char rpaname[] = "IBM,RPA-Client-Config"; + +/* + * Note: setting ignore_my_client_config *should* mean that OF ignores + * all the other fields, but there is a firmware bug which means that + * it looks at the splpar field at least. So these values need to be + * reasonable. + */ +#define N_RPA_DESCR 8 +unsigned int rpanote[N_RPA_DESCR] = { + 0, /* lparaffinity */ + 64, /* min_rmo_size */ + 0, /* min_rmo_percent */ + 40, /* max_pft_size */ + 1, /* splpar */ + -1, /* min_load */ + 0, /* new_mem_def */ + 1, /* ignore_my_client_config */ +}; + +#define ROUNDUP(len) (((len) + 3) & ~3) + +unsigned char buf[512]; + +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) + +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) + +/* Structure of an ELF file */ +#define E_IDENT 0 /* ELF header */ +#define E_PHOFF 28 +#define E_PHENTSIZE 42 +#define E_PHNUM 44 +#define E_HSIZE 52 /* size of ELF header */ + +#define EI_MAGIC 0 /* offsets in E_IDENT area */ +#define EI_CLASS 4 +#define EI_DATA 5 + +#define PH_TYPE 0 /* ELF program header */ +#define PH_OFFSET 4 +#define PH_FILESZ 16 +#define PH_HSIZE 32 /* size of program header */ + +#define PT_NOTE 4 /* Program header type = note */ + +#define ELFCLASS32 1 +#define ELFDATA2MSB 2 + +unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; + +int +main(int ac, char **av) +{ + int fd, n, i; + int ph, ps, np; + int nnote, nnote2, ns; + + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); + exit(1); + } + fd = open(av[1], O_RDWR); + if (fd < 0) { + perror(av[1]); + exit(1); + } + + nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); + nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); + + n = read(fd, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + exit(1); + } + + if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) + goto notelf; + + if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 + || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { + fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", + av[1]); + exit(1); + } + + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); + if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) + goto notelf; + if (ph + (np + 2) * ps + nnote + nnote2 > n) + goto nospace; + + for (i = 0; i < np; ++i) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { + fprintf(stderr, "%s already has a note entry\n", + av[1]); + exit(0); + } + ph += ps; + } + + /* XXX check that the area we want to use is all zeroes */ + for (i = 0; i < 2 * ps + nnote + nnote2; ++i) + if (buf[ph + i] != 0) + goto nospace; + + /* fill in the program header entry */ + ns = ph + 2 * ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); + + /* fill in the note area we point to */ + /* XXX we should probably make this a proper section */ + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); + strcpy((char *) &buf[ns + 12], arch); + ns += 12 + strlen(arch) + 1; + for (i = 0; i < N_DESCR; ++i, ns += 4) + PUT_32BE(ns, descr[i]); + + /* fill in the second program header entry and the RPA note area */ + ph += ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote2); + + /* fill in the note area we point to */ + PUT_32BE(ns, strlen(rpaname) + 1); + PUT_32BE(ns + 4, sizeof(rpanote)); + PUT_32BE(ns + 8, 0x12759999); + strcpy((char *) &buf[ns + 12], rpaname); + ns += 12 + ROUNDUP(strlen(rpaname) + 1); + for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) + PUT_32BE(ns, rpanote[i]); + + /* Update the number of program headers */ + PUT_16BE(E_PHNUM, np + 2); + + /* write back */ + lseek(fd, (long) 0, SEEK_SET); + i = write(fd, buf, n); + if (i < 0) { + perror("write"); + exit(1); + } + if (i < n) { + fprintf(stderr, "%s: write truncated\n", av[1]); + exit(1); + } + + exit(0); + + notelf: + fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); + exit(1); + + nospace: + fprintf(stderr, "sorry, I can't find space in %s to put the note\n", + av[1]); + exit(1); +} diff --git a/util-linux-2.14.1-hwclock_adjust_and_hctosys.patch b/util-linux-2.14.1-hwclock_adjust_and_hctosys.patch new file mode 100644 index 0000000..24dc201 --- /dev/null +++ b/util-linux-2.14.1-hwclock_adjust_and_hctosys.patch @@ -0,0 +1,170 @@ +From: Kurt Garloff +Subject: Allow to combine --adjust and --hctosys +Reference: bnc441106 + +Waiting for a clock tick twice when calling --adjust and --hctosys +is wasteful. Having to do it once is bad enough. +This patch allows combining the two options. + +[Patch 1/5] + +Index: util-linux-ng-2.14.1/hwclock/hwclock.c +=================================================================== +--- util-linux-ng-2.14.1.orig/hwclock/hwclock.c ++++ util-linux-ng-2.14.1/hwclock/hwclock.c +@@ -490,13 +490,18 @@ set_hardware_clock(const time_t newtime, + } + + + ++static int ++set_system_clock(const bool hclock_valid, const time_t newtime, ++ const bool testing, const int usec); ++ + static void + set_hardware_clock_exact(const time_t sethwtime, + const struct timeval refsystime, + const bool universal, +- const bool testing) { ++ const bool testing, ++ const bool hctosys) { + /*---------------------------------------------------------------------------- + Set the Hardware Clock to the time "sethwtime", in local time zone or UTC, + according to "universal". + +@@ -539,8 +544,10 @@ set_hardware_clock_exact(const time_t se + if (tdiff < 0) + goto time_resync; /* probably time was reset */ + } while (time_diff(nowsystime, refsystime) - 0.5 < newhwtime - sethwtime); + ++ if (hctosys) ++ set_system_clock(TRUE, newhwtime, testing, 500000); + set_hardware_clock(newhwtime, universal, testing); + } + + +@@ -671,9 +678,9 @@ interpret_date_string(const char *date_o + + + static int + set_system_clock(const bool hclock_valid, const time_t newtime, +- const bool testing) { ++ const bool testing, const int usec) { + /*---------------------------------------------------------------------------- + Set the System Clock to time 'newtime'. + + Also set the kernel time zone value to the value indicated by the +@@ -699,9 +706,9 @@ set_system_clock(const bool hclock_valid + int minuteswest; + int rc; + + tv.tv_sec = newtime; +- tv.tv_usec = 0; ++ tv.tv_usec = usec; + + broken = localtime(&newtime); + #ifdef HAVE_TM_GMTOFF + minuteswest = -broken->tm_gmtoff/60; /* GNU extension */ +@@ -935,9 +942,10 @@ save_adjtime(const struct adjtime adjtim + static void + do_adjustment(struct adjtime *adjtime_p, + const bool hclock_valid, const time_t hclocktime, + const struct timeval read_time, +- const bool universal, const bool testing) { ++ const bool universal, const bool testing, ++ const bool hctosys) { + /*--------------------------------------------------------------------------- + Do the adjustment requested, by 1) setting the Hardware Clock (if + necessary), and 2) updating the last-adjusted time in the adjtime + structure. +@@ -990,9 +998,9 @@ do_adjustment(struct adjtime *adjtime_p, + &adjustment, &retro); + if (adjustment > 0 || adjustment < -1) { + set_hardware_clock_exact(hclocktime + adjustment, + time_inc(read_time, -retro), +- universal, testing); ++ universal, testing, hctosys); + adjtime_p->last_adj_time = hclocktime + adjustment; + adjtime_p->not_adjusted = 0; + adjtime_p->dirty = TRUE; + } else +@@ -1046,8 +1054,9 @@ manipulate_clock(const bool show, const + struct adjtime adjtime; + /* Contents of the adjtime file, or what they should be. */ + int rc; /* local return code */ + bool no_auth; /* User lacks necessary authorization to access the clock */ ++ int usec = 0; + + no_auth = ur->get_permissions(); + if (no_auth) + return EX_NOPERM; +@@ -1097,15 +1106,15 @@ manipulate_clock(const bool show, const + display_time(hclock_valid, hclocktime, + time_diff(read_time, startup_time)); + } else if (set) { + set_hardware_clock_exact(set_time, startup_time, +- universal, testing); ++ universal, testing, FALSE); + if (!noadjfile) + adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime, + time_diff(read_time, startup_time)); + } else if (adjust) { + do_adjustment(&adjtime, hclock_valid, hclocktime, +- read_time, universal, testing); ++ read_time, universal, testing, hctosys); + } else if (systohc) { + struct timeval nowtime, reftime; + /* We can only set_hardware_clock_exact to a whole seconds + time, so we set it with reference to the most recent +@@ -1115,14 +1124,14 @@ manipulate_clock(const bool show, const + reftime.tv_sec = nowtime.tv_sec; + reftime.tv_usec = 0; + + set_hardware_clock_exact((time_t) reftime.tv_sec, reftime, +- universal, testing); ++ universal, testing, FALSE); + if (!noadjfile) + adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid, + hclocktime, (double) read_time.tv_usec / 1E6); + } else if (hctosys) { +- rc = set_system_clock(hclock_valid, hclocktime, testing); ++ rc = set_system_clock(hclock_valid, hclocktime, testing, usec); + if (rc) { + printf(_("Unable to set system clock.\n")); + return rc; + } +@@ -1442,9 +1451,16 @@ main(int argc, char **argv) { + "You supplied %d.\n"), + MYNAME, argc); + } + +- if (show + set + systohc + hctosys + adjust + getepoch + setepoch > 1){ ++ if (show + set + systohc + hctosys + getepoch + setepoch > 1){ ++ fprintf(stderr, _("You have specified multiple functions.\n" ++ "You can only perform one function " ++ "at a time.\n")); ++ hwclock_exit(EX_USAGE); ++ } ++ ++ if (show + set + systohc + adjust + getepoch + setepoch > 1){ + fprintf(stderr, _("You have specified multiple functions.\n" + "You can only perform one function " + "at a time.\n")); + hwclock_exit(EX_USAGE); +Index: util-linux-ng-2.14.1/hwclock/hwclock.8 +=================================================================== +--- util-linux-ng-2.14.1.orig/hwclock/hwclock.8 ++++ util-linux-ng-2.14.1/hwclock/hwclock.8 +@@ -86,8 +86,12 @@ Set the Hardware Clock to the current Sy + .B \-\-adjust + Add or subtract time from the Hardware Clock to account for systematic + drift since the last time the clock was set or adjusted. See discussion + below. ++.B \-\-adjust ++can be used together with ++.B \-\-hctosys ++to speed up the boot process by 1s. + .TP + .B \-\-getepoch + Print the kernel's Hardware Clock epoch value to standard output. + This is the number of years into AD to which a zero year value in the diff --git a/util-linux-2.14.1-mount_race.patch b/util-linux-2.14.1-mount_race.patch new file mode 100644 index 0000000..23a232f --- /dev/null +++ b/util-linux-2.14.1-mount_race.patch @@ -0,0 +1,151 @@ +Index: util-linux-ng-2.14.1/mount/fstab.c +=================================================================== +--- util-linux-ng-2.14.1.orig/mount/fstab.c 2008-05-29 01:01:02.000000000 +0200 ++++ util-linux-ng-2.14.1/mount/fstab.c 2008-11-18 18:08:59.000000000 +0100 +@@ -773,8 +773,6 @@ update_mtab (const char *dir, struct my_ + if (mtab_does_not_exist() || !mtab_is_writable()) + return; + +- lock_mtab(); +- + /* having locked mtab, read it again */ + mc0 = mc = &mtabhead; + mc->nxt = mc->prev = NULL; +@@ -893,7 +891,7 @@ update_mtab (const char *dir, struct my_ + } + + leave: +- unlock_mtab(); ++ ; + } + + +Index: util-linux-ng-2.14.1/mount/umount.c +=================================================================== +--- util-linux-ng-2.14.1.orig/mount/umount.c 2008-07-02 15:08:50.000000000 +0200 ++++ util-linux-ng-2.14.1/mount/umount.c 2008-11-19 17:17:36.000000000 +0100 +@@ -102,6 +102,8 @@ check_special_umountprog(const char *spe + if (strlen(type) < 100) { + sprintf(umountprog, "/sbin/umount.%s", type); + if (stat(umountprog, &statbuf) == 0) { ++ /* unlock mtab if we need to exec */ ++ unlock_mtab(); + res = fork(); + if (res == 0) { + char *umountargs[8]; +@@ -383,6 +385,7 @@ umount_all (char *types, char *test_opts + struct mntentchn *mc, *hd; + int errors = 0; + ++ lock_mtab(); + hd = mtab_head(); + if (!hd->prev) + die (2, _("umount: cannot find list of filesystems to unmount")); +@@ -393,6 +396,7 @@ umount_all (char *types, char *test_opts + mc->m.mnt_type, mc->m.mnt_opts, mc); + } + } ++ unlock_mtab(); + + sync (); + return errors; +@@ -463,6 +467,7 @@ umount_file (char *arg) { + const char *file, *options; + int fstab_has_user, fstab_has_users, fstab_has_owner, fstab_has_group; + int ok; ++ int ret; + + if (!*arg) { /* "" would be expanded to `pwd` */ + die(2, _("Cannot umount \"\"\n")); +@@ -473,6 +478,7 @@ umount_file (char *arg) { + if (verbose > 1) + printf(_("Trying to umount %s\n"), file); + ++ lock_mtab(); + mc = getmntdirbackward(file, NULL); + if (!mc) + mc = getmntdevbackward(file, NULL); +@@ -572,9 +578,12 @@ umount_file (char *arg) { + } + + if (mc) +- return umount_one_bw (file, mc); ++ ret = umount_one_bw (file, mc); + else +- return umount_one (arg, arg, arg, arg, NULL); ++ ret = umount_one (arg, arg, arg, arg, NULL); ++ ++ unlock_mtab(); ++ return ret; + } + + int +Index: util-linux-ng-2.14.1/mount/mount.c +=================================================================== +--- util-linux-ng-2.14.1.orig/mount/mount.c 2008-11-18 18:08:59.000000000 +0100 ++++ util-linux-ng-2.14.1/mount/mount.c 2008-11-18 18:09:04.000000000 +0100 +@@ -521,8 +521,6 @@ create_mtab (void) { + int flags; + mntFILE *mfp; + +- lock_mtab(); +- + mfp = my_setmntent (_PATH_MOUNTED, "a+"); + if (mfp == NULL || mfp->mntent_fp == NULL) { + int errsv = errno; +@@ -556,8 +554,6 @@ create_mtab (void) { + } + my_endmntent (mfp); + +- unlock_mtab(); +- + reset_mtab_info(); + } + +@@ -1004,7 +1000,6 @@ update_mtab_entry(const char *spec, cons + else { + mntFILE *mfp; + +- lock_mtab(); + mfp = my_setmntent(_PATH_MOUNTED, "a+"); + if (mfp == NULL || mfp->mntent_fp == NULL) { + int errsv = errno; +@@ -1018,7 +1013,6 @@ update_mtab_entry(const char *spec, cons + } + } + my_endmntent(mfp); +- unlock_mtab(); + } + } + my_free(mnt.mnt_fsname); +@@ -1138,12 +1132,14 @@ try_mount_one (const char *spec0, const + + mount_retry: + block_signals (SIG_BLOCK); ++ lock_mtab(); + + if (!fake) { + mnt5_res = guess_fstype_and_mount (spec, node, &types, flags & ~MS_NOSYS, + mount_opts, &special, &status); + + if (special) { ++ unlock_mtab(); + block_signals (SIG_UNBLOCK); + res = status; + goto out; +@@ -1163,6 +1159,7 @@ mount_retry: + pass); + } + ++ unlock_mtab(); + block_signals (SIG_UNBLOCK); + res = 0; + goto out; +@@ -1173,6 +1170,7 @@ mount_retry: + if (loop) + del_loop(spec); + ++ unlock_mtab(); + block_signals (SIG_UNBLOCK); + + /* Mount failed, complain, but don't die. */ diff --git a/util-linux-2.14.1-mount_skip_sync.patch b/util-linux-2.14.1-mount_skip_sync.patch new file mode 100644 index 0000000..7f5a3ab --- /dev/null +++ b/util-linux-2.14.1-mount_skip_sync.patch @@ -0,0 +1,27 @@ +Index: util-linux-ng-2.14.1/mount/umount.c +=================================================================== +--- util-linux-ng-2.14.1.orig/mount/umount.c 2008-11-20 15:01:09.000000000 +0100 ++++ util-linux-ng-2.14.1/mount/umount.c 2008-11-20 15:04:39.000000000 +0100 +@@ -384,6 +384,7 @@ static int + umount_all (char *types, char *test_opts) { + struct mntentchn *mc, *hd; + int errors = 0; ++ int do_sync = 0; + + lock_mtab(); + hd = mtab_head(); +@@ -394,11 +395,13 @@ umount_all (char *types, char *test_opts + && matching_opts (mc->m.mnt_opts, test_opts)) { + errors |= umount_one (mc->m.mnt_fsname, mc->m.mnt_dir, + mc->m.mnt_type, mc->m.mnt_opts, mc); ++ do_sync = 1; + } + } + unlock_mtab(); + +- sync (); ++ if (do_sync) ++ sync (); + return errors; + } + diff --git a/util-linux.changes b/util-linux.changes index 3eb1c76..42c9a3a 100644 --- a/util-linux.changes +++ b/util-linux.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Thu Nov 20 18:08:33 CET 2008 - mkoenig@suse.de + +- mount: enhance mount/umount mtab locking and lock the whole + read mtab/syscall/write mtab process to avoid mtab corruption + with highly concurrent mount/umount calls [bnc#444966] +- add arch/powerpc/boot/addnote.c from kernel 2.6.27 + as /usr/bin/chrp-addnote [bnc#443859] +- umount: skip sync() in umount -a if no umount happened [bnc#447036] +- hwclock: allow --adjust and --hctosys simultaneously [bnc#441106] + ------------------------------------------------------------------- Fri Nov 7 14:50:00 CET 2008 - mkoenig@suse.de diff --git a/util-linux.spec b/util-linux.spec index bdc086c..54f6a7e 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -30,7 +30,7 @@ License: BSD 3-Clause; GPL v2 or later Group: System/Base AutoReqProv: on Version: 2.14.1 -Release: 6 +Release: 7 Requires: %name-lang = %{version} Summary: A collection of basic system utilities Source: ftp://ftp.kernel.org/pub/linux/utils/util-linux/%name-ng-%version.tar.bz2 @@ -57,6 +57,7 @@ Source26: README.raw Source28: mkzimage_cmdline.8 Source29: mkzimage_cmdline.c Source30: README.largedisk +Source31: addnote.c ## ## util-linux patches ## @@ -80,6 +81,9 @@ Patch13: util-linux-2.14.1-disk-utils_mkfs.minix_file_size_detection.patc Patch14: util-linux-2.14.1-fdisk_missing_include.patch Patch15: util-linux-2.14.1-fdisk_cylinder.patch Patch16: util-linux-2.14.1-mount_loop_ro_fix.patch +Patch17: util-linux-2.14.1-mount_race.patch +Patch18: util-linux-2.14.1-mount_skip_sync.patch +Patch19: util-linux-2.14.1-hwclock_adjust_and_hctosys.patch # crypto patch Patch20: util-linux-mount_losetup_crypto.patch ## @@ -132,6 +136,9 @@ Authors: %patch14 -p1 %patch15 -p1 %patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 %patch20 -p1 cp %{SOURCE7} %{SOURCE8} . # @@ -222,6 +229,7 @@ autoreconf -fi make gcc $RPM_OPT_FLAGS -o nologin nologin.c gcc $RPM_OPT_FLAGS -o mkzimage_cmdline %{S:29} +gcc $RPM_OPT_FLAGS -o chrp-addnote %{SOURCE31} %check cd ../time-%{time_ver} @@ -272,6 +280,7 @@ install -m 755 nologin $RPM_BUILD_ROOT/sbin %ifnarch ppc ppc64 install -m 755 mkzimage_cmdline $RPM_BUILD_ROOT/usr/bin install -m 644 %{S:28} $RPM_BUILD_ROOT%{_mandir}/man8 +install -m 755 chrp-addnote $RPM_BUILD_ROOT/usr/bin %endif install -m 644 nologin.8 $RPM_BUILD_ROOT%{_mandir}/man8 # setctsid install @@ -284,7 +293,7 @@ install -m 644 $RPM_SOURCE_DIR/etc.raw $RPM_BUILD_ROOT/etc/raw install -m 755 $RPM_SOURCE_DIR/raw.init $RPM_BUILD_ROOT/etc/init.d/raw ln -sf ../../etc/init.d/raw $RPM_BUILD_ROOT/usr/sbin/rcraw # Stupid hack so we don't have a tcsh dependency -#chmod 644 $RPM_BUILD_ROOT/usr/share/misc/getopt/* +chmod 644 $RPM_BUILD_ROOT/usr/share/getopt/getopt*.tcsh # Following files we don't want to package, so remove them rm -f $RPM_BUILD_ROOT/usr/bin/pg rm -f $RPM_BUILD_ROOT/usr/share/man/man1/pg.1* @@ -431,6 +440,7 @@ fi /usr/bin/mcookie /usr/bin/mesg %ifnarch ppc ppc64 +/usr/bin/chrp-addnote /usr/bin/mkzimage_cmdline %endif /usr/bin/namei @@ -599,6 +609,14 @@ fi #%endif %changelog +* Thu Nov 20 2008 mkoenig@suse.de +- mount: enhance mount/umount mtab locking and lock the whole + read mtab/syscall/write mtab process to avoid mtab corruption + with highly concurrent mount/umount calls [bnc#444966] +- add arch/powerpc/boot/addnote.c from kernel 2.6.27 + as /usr/bin/chrp-addnote [bnc#443859] +- umount: skip sync() in umount -a if no umount happened [bnc#447036] +- hwclock: allow --adjust and --hctosys simultaneously [bnc#441106] * Fri Nov 07 2008 mkoenig@suse.de - fdisk: support +cylinder notation [bnc#441871] - check for EACCES when using ro fallback when loop mounting