]> git.pld-linux.org Git - packages/util-linux.git/commitdiff
- patches from fedora (details in patches if not obvious)
authorJan Rękorajski <baggins@pld-linux.org>
Sat, 24 Mar 2007 21:20:38 +0000 (21:20 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    util-linux-audit-hwclock.patch -> 1.1
    util-linux-audit-login.patch -> 1.1
    util-linux-chsh.patch -> 1.1
    util-linux-col-EILSEQ.patch -> 1.1
    util-linux-cramfs-maxentries.patch -> 1.1
    util-linux-cramfs-zerofiles.patch -> 1.1
    util-linux-ctrlaltdel-man.patch -> 1.1
    util-linux-ctty3.patch -> 1.1
    util-linux-execl.patch -> 1.1
    util-linux-fdformat-ide.patch -> 1.1
    util-linux-fdisk-b-4096.patch -> 1.1
    util-linux-fdisk-gpt.patch -> 1.1
    util-linux-fdisk-isfull.patch -> 1.1
    util-linux-fdisk-sectors.patch -> 1.1
    util-linux-fdisksegv.patch -> 1.1
    util-linux-hexdump-gcc.patch -> 1.1
    util-linux-hotkeys.patch -> 1.1
    util-linux-ipcs-shmax.patch -> 1.1
    util-linux-ipcs-typo.patch -> 1.1
    util-linux-login-hang.patch -> 1.1
    util-linux-login-ipv6.patch -> 1.1
    util-linux-login-lastlog.patch -> 1.1
    util-linux-login-pam-acct.patch -> 1.1
    util-linux-login-timeval.patch -> 1.1
    util-linux-look-separator.patch -> 1.1
    util-linux-losetup-all.patch -> 1.1
    util-linux-losetup-deprecated.patch -> 1.1
    util-linux-losetup-rdonly.patch -> 1.1
    util-linux-lvm2dupes.patch -> 1.1
    util-linux-mkswap-mounted.patch -> 1.1
    util-linux-mkswap-selinux.patch -> 1.1
    util-linux-more-CLOEXEC.patch -> 1.1
    util-linux-mount-context.patch -> 1.1
    util-linux-mount-man-bugs.patch -> 1.1
    util-linux-mount-man-cifs.patch -> 1.1
    util-linux-mount-man-nfs.patch -> 1.1
    util-linux-mount-man-nfs4.patch -> 1.1
    util-linux-mount-nonfs.patch -> 1.1
    util-linux-mount-sloppy.patch -> 1.1
    util-linux-mount-subtree.patch -> 1.1
    util-linux-mount-twiceloop.patch -> 1.1
    util-linux-mount-uhelper.patch -> 1.1
    util-linux-mount-uuid.patch -> 1.1
    util-linux-mountbylabel-dm.patch -> 1.1
    util-linux-mtab-lock.patch -> 1.1
    util-linux-multibyte.patch -> 1.1
    util-linux-namei-logic.patch -> 1.1
    util-linux-pamsession.patch -> 1.1
    util-linux-partx-man.patch -> 1.1
    util-linux-procpartitions.patch -> 1.1
    util-linux-raw-handle-nonpresent-devs.patch -> 1.1
    util-linux-raw-man.patch -> 1.1
    util-linux-raw-raw0.patch -> 1.1
    util-linux-rdev-man.patch -> 1.1
    util-linux-schedutils-SCHED_BATCH.patch -> 1.1
    util-linux-schedutils-man.patch -> 1.1
    util-linux-skipraid2.patch -> 1.1
    util-linux-swap-page.patch -> 1.1
    util-linux-swapon-suspend.patch -> 1.1
    util-linux-swaponsymlink.patch -> 1.1
    util-linux-umount-sysfs.patch -> 1.1

61 files changed:
util-linux-audit-hwclock.patch [new file with mode: 0644]
util-linux-audit-login.patch [new file with mode: 0644]
util-linux-chsh.patch [new file with mode: 0644]
util-linux-col-EILSEQ.patch [new file with mode: 0644]
util-linux-cramfs-maxentries.patch [new file with mode: 0644]
util-linux-cramfs-zerofiles.patch [new file with mode: 0644]
util-linux-ctrlaltdel-man.patch [new file with mode: 0644]
util-linux-ctty3.patch [new file with mode: 0644]
util-linux-execl.patch [new file with mode: 0644]
util-linux-fdformat-ide.patch [new file with mode: 0644]
util-linux-fdisk-b-4096.patch [new file with mode: 0644]
util-linux-fdisk-gpt.patch [new file with mode: 0644]
util-linux-fdisk-isfull.patch [new file with mode: 0644]
util-linux-fdisk-sectors.patch [new file with mode: 0644]
util-linux-fdisksegv.patch [new file with mode: 0644]
util-linux-hexdump-gcc.patch [new file with mode: 0644]
util-linux-hotkeys.patch [new file with mode: 0644]
util-linux-ipcs-shmax.patch [new file with mode: 0644]
util-linux-ipcs-typo.patch [new file with mode: 0644]
util-linux-login-hang.patch [new file with mode: 0644]
util-linux-login-ipv6.patch [new file with mode: 0644]
util-linux-login-lastlog.patch [new file with mode: 0644]
util-linux-login-pam-acct.patch [new file with mode: 0644]
util-linux-login-timeval.patch [new file with mode: 0644]
util-linux-look-separator.patch [new file with mode: 0644]
util-linux-losetup-all.patch [new file with mode: 0644]
util-linux-losetup-deprecated.patch [new file with mode: 0644]
util-linux-losetup-rdonly.patch [new file with mode: 0644]
util-linux-lvm2dupes.patch [new file with mode: 0644]
util-linux-mkswap-mounted.patch [new file with mode: 0644]
util-linux-mkswap-selinux.patch [new file with mode: 0644]
util-linux-more-CLOEXEC.patch [new file with mode: 0644]
util-linux-mount-context.patch [new file with mode: 0644]
util-linux-mount-man-bugs.patch [new file with mode: 0644]
util-linux-mount-man-cifs.patch [new file with mode: 0644]
util-linux-mount-man-nfs.patch [new file with mode: 0644]
util-linux-mount-man-nfs4.patch [new file with mode: 0644]
util-linux-mount-nonfs.patch [new file with mode: 0644]
util-linux-mount-sloppy.patch [new file with mode: 0644]
util-linux-mount-subtree.patch [new file with mode: 0644]
util-linux-mount-twiceloop.patch [new file with mode: 0644]
util-linux-mount-uhelper.patch [new file with mode: 0644]
util-linux-mount-uuid.patch [new file with mode: 0644]
util-linux-mountbylabel-dm.patch [new file with mode: 0644]
util-linux-mtab-lock.patch [new file with mode: 0644]
util-linux-multibyte.patch [new file with mode: 0644]
util-linux-namei-logic.patch [new file with mode: 0644]
util-linux-pamsession.patch [new file with mode: 0644]
util-linux-partx-man.patch [new file with mode: 0644]
util-linux-procpartitions.patch [new file with mode: 0644]
util-linux-raw-handle-nonpresent-devs.patch [new file with mode: 0644]
util-linux-raw-man.patch [new file with mode: 0644]
util-linux-raw-raw0.patch [new file with mode: 0644]
util-linux-rdev-man.patch [new file with mode: 0644]
util-linux-schedutils-SCHED_BATCH.patch [new file with mode: 0644]
util-linux-schedutils-man.patch [new file with mode: 0644]
util-linux-skipraid2.patch [new file with mode: 0644]
util-linux-swap-page.patch [new file with mode: 0644]
util-linux-swapon-suspend.patch [new file with mode: 0644]
util-linux-swaponsymlink.patch [new file with mode: 0644]
util-linux-umount-sysfs.patch [new file with mode: 0644]

diff --git a/util-linux-audit-hwclock.patch b/util-linux-audit-hwclock.patch
new file mode 100644 (file)
index 0000000..1d4dff8
--- /dev/null
@@ -0,0 +1,316 @@
+- util-linux updates for new audit system
+
+diff -urN util-linux-2.13-pre5.orig/hwclock/audit.c util-linux-2.13-pre5/hwclock/audit.c
+--- util-linux-2.13-pre5.orig/hwclock/audit.c  1969-12-31 19:00:00.000000000 -0500
++++ util-linux-2.13-pre5/hwclock/audit.c       2005-10-25 17:14:46.000000000 -0400
+@@ -0,0 +1,50 @@
++/* audit.c -- This file contains the audit system extensions
++ *
++ * Copyright 2005 Red Hat Inc., Durham, North Carolina.
++ * All Rights Reserved.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * Authors:
++ *     Steve Grubb <sgrubb@redhat.com>
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <libaudit.h>
++#include "audit.h"
++
++int audit_fd = -1;
++static int audit_this = 0;
++
++
++void auditable_event(int i)
++{
++      audit_this = i;
++}
++
++
++void audit_exit(int status)
++{
++      if (audit_this) {
++              audit_log_user_message(audit_fd, AUDIT_USYS_CONFIG, 
++                      "changing system time", NULL, NULL, NULL, status ? 0 : 1);
++              close(audit_fd);
++      }
++      exit(status);
++}
++
+diff -urN util-linux-2.13-pre5.orig/hwclock/audit.h util-linux-2.13-pre5/hwclock/audit.h
+--- util-linux-2.13-pre5.orig/hwclock/audit.h  1969-12-31 19:00:00.000000000 -0500
++++ util-linux-2.13-pre5/hwclock/audit.h       2005-10-25 17:09:40.000000000 -0400
+@@ -0,0 +1,34 @@
++/* audit.h -- This file contains the function prototypes for audit calls
++ * Copyright 2005 Red Hat Inc., Durham, North Carolina.
++ * All Rights Reserved.
++ *
++ * 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.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * Author:
++ *   Steve Grubb <sgrubb@redhat.com>
++ *
++ */
++
++#ifndef HW_AUDIT_H
++#define HW_AUDIT_H
++
++/* This is the file descriptor used by the audit system */
++extern int audit_fd;
++
++/* This is the logging functions */
++void auditable_event(int i);
++void audit_exit(int status);
++
++#endif
+diff -urN util-linux-2.13-pre5.orig/hwclock/clock.h util-linux-2.13-pre5/hwclock/clock.h
+--- util-linux-2.13-pre5.orig/hwclock/clock.h  2005-10-25 17:08:26.000000000 -0400
++++ util-linux-2.13-pre5/hwclock/clock.h       2005-10-25 17:09:40.000000000 -0400
+@@ -24,7 +24,12 @@
+ extern char *progname;
+ extern int debug;
+ extern int epoch_option;
+-extern void outsyserr(char *msg, ...);
++extern void outsyserr(char *msg, ...)
++#ifdef __GNUC__
++        __attribute__ ((format (printf, 1, 2)));
++#else
++        ;
++#endif
+ /* cmos.c */
+ extern void set_cmos_epoch(int ARCconsole, int SRM);
+diff -urN util-linux-2.13-pre5.orig/hwclock/hwclock.c util-linux-2.13-pre5/hwclock/hwclock.c
+--- util-linux-2.13-pre5.orig/hwclock/hwclock.c        2005-10-25 17:08:26.000000000 -0400
++++ util-linux-2.13-pre5/hwclock/hwclock.c     2005-10-25 17:09:40.000000000 -0400
+@@ -81,9 +81,11 @@
+ #include <stdarg.h>
+ #include <getopt.h>
+ #include <sysexits.h>
++#include <libaudit.h>
+ #include "clock.h"
+ #include "nls.h"
++#include "audit.h"
+ #define MYNAME "hwclock"
+@@ -1234,7 +1236,7 @@
+     va_end(ap);
+   }
+  
+-  exit(fmt ? EX_USAGE : 0);
++  audit_exit(fmt ? EX_USAGE : 0);
+ }
+ static const struct option longopts[] = {
+@@ -1298,6 +1300,15 @@
+       /* Remember what time we were invoked */
+       gettimeofday(&startup_time, NULL);
++      audit_fd = audit_open();
++      if (audit_fd < 0 && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
++                              errno == EAFNOSUPPORT)) {
++              /* You get these error codes only when the kernel doesn't have
++               * audit compiled in. */
++              fprintf(stderr, "Error - unable to connect to audit system\n");
++              return EX_NOPERM;
++      }
++
+       setlocale(LC_ALL, "");
+ #ifdef LC_NUMERIC
+       /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
+@@ -1393,6 +1404,13 @@
+       argc -= optind;
+       argv += optind;
++      if (testing != TRUE) {
++              if (adjust == TRUE || hctosys == TRUE || systohc == TRUE ||
++                      set == TRUE || setepoch == TRUE) {
++                      auditable_event(1);
++              }
++      }
++
+       if (argc > 0) {
+               usage(_("%s takes no non-option arguments.  "
+                       "You supplied %d.\n"),
+@@ -1403,27 +1421,27 @@
+               fprintf(stderr, _("You have specified multiple functions.\n"
+                                 "You can only perform one function "
+                                 "at a time.\n"));
+-              exit(EX_USAGE);
++              audit_exit(EX_USAGE);
+       }
+       if (utc && local_opt) {
+               fprintf(stderr, _("%s: The --utc and --localtime options "
+                                 "are mutually exclusive.  You specified "
+                                 "both.\n"), MYNAME);
+-              exit(EX_USAGE);
++              audit_exit(EX_USAGE);
+       }
+       if (adjust && noadjfile) {
+               fprintf(stderr, _("%s: The --adjust and --noadjfile options "
+                                 "are mutually exclusive.  You specified "
+                                 "both.\n"), MYNAME);
+-              exit(EX_USAGE);
++              audit_exit(EX_USAGE);
+       }
+       if (noadjfile && !(utc || local_opt)) {
+               fprintf(stderr, _("%s: With --noadjfile, you must specify "
+                                 "either --utc or --localtime\n"), MYNAME);
+-              exit(EX_USAGE);
++              audit_exit(EX_USAGE);
+       }
+ #ifdef __alpha__
+@@ -1437,7 +1455,7 @@
+               if (rc != 0) {
+                       fprintf(stderr, _("No usable set-to time.  "
+                                         "Cannot set clock.\n"));
+-                      exit(EX_USAGE);
++                      audit_exit(EX_USAGE);
+               }
+       }
+@@ -1469,11 +1487,11 @@
+       }
+       if (!permitted)
+-              exit(EX_NOPERM);
++              audit_exit(EX_NOPERM);
+       if (getepoch || setepoch) {
+               manipulate_epoch(getepoch, setepoch, epoch_option, testing);
+-              return 0;
++              audit_exit(0);
+       }
+       if (debug)
+@@ -1487,12 +1505,14 @@
+                       fprintf(stderr,
+                               _("Use the --debug option to see the details "
+                                 "of our search for an access method.\n"));
+-              exit(1);
++              audit_exit(1);
+       }
+-      return manipulate_clock(show, adjust, noadjfile, set, set_time,
++      rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
+                               hctosys, systohc, startup_time, utc,
+                               local_opt, testing);
++      audit_exit(rc);
++      return rc;      /* Not reached */
+ }
+ /* A single routine for greater uniformity */
+diff -urN util-linux-2.13-pre5.orig/hwclock/kd.c util-linux-2.13-pre5/hwclock/kd.c
+--- util-linux-2.13-pre5.orig/hwclock/kd.c     2005-10-25 17:08:26.000000000 -0400
++++ util-linux-2.13-pre5/hwclock/kd.c  2005-10-25 17:09:40.000000000 -0400
+@@ -19,6 +19,7 @@
+ #include "clock.h"
+ #include "nls.h"
++#include "audit.h"
+ static int con_fd = -1;               /* opened by probe_for_kd_clock() */
+                               /* never closed */
+@@ -103,7 +104,7 @@
+   if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
+     outsyserr(_("ioctl() failed to read time from %s"), con_fd_filename);
+-    exit(EX_IOERR);
++    audit_exit(EX_IOERR);
+   }
+   tm->tm_sec  = t.sec;
+@@ -139,7 +140,7 @@
+   if (ioctl(con_fd, KDSHWCLK, &t ) == -1) {
+     outsyserr(_("ioctl KDSHWCLK failed"));
+-    exit(1);
++    audit_exit(1);
+   }
+   return 0;
+ }
+diff -urN util-linux-2.13-pre5.orig/hwclock/Makefile.am util-linux-2.13-pre5/hwclock/Makefile.am
+--- util-linux-2.13-pre5.orig/hwclock/Makefile.am      2005-10-25 17:08:26.000000000 -0400
++++ util-linux-2.13-pre5/hwclock/Makefile.am   2005-10-25 17:09:40.000000000 -0400
+@@ -4,4 +4,5 @@
+ sbin_PROGRAMS = hwclock
+-hwclock_SOURCES = hwclock.c cmos.c rtc.c kd.c
+\ No newline at end of file
++hwclock_SOURCES = hwclock.c cmos.c rtc.c kd.c audit.c
++hwclock_LDADD = -laudit
+\ No newline at end of file
+diff -urN util-linux-2.13-pre5.orig/hwclock/rtc.c util-linux-2.13-pre5/hwclock/rtc.c
+--- util-linux-2.13-pre5.orig/hwclock/rtc.c    2005-10-25 17:08:26.000000000 -0400
++++ util-linux-2.13-pre5/hwclock/rtc.c 2005-10-25 17:09:40.000000000 -0400
+@@ -8,6 +8,7 @@
+ #include "clock.h"
+ #include "nls.h"
++#include "audit.h"
+ /*
+  * Get defines for rtc stuff.
+@@ -114,7 +115,7 @@
+       if (rtc_fd < 0) {
+               outsyserr(_("open() of %s failed"), rtc_dev_name);
+-              exit(EX_OSFILE);
++              audit_exit(EX_OSFILE);
+       }
+       return rtc_fd;
+ }
+@@ -149,7 +150,7 @@
+               perror(ioctlname);
+               fprintf(stderr, _("ioctl() to %s to read the time failed.\n"),
+                       rtc_dev_name);
+-              exit(EX_IOERR);
++              audit_exit(EX_IOERR);
+       }
+       tm->tm_isdst = -1;          /* don't know whether it's dst */
+@@ -329,7 +330,7 @@
+               perror(ioctlname);
+               fprintf(stderr, _("ioctl() to %s to set the time failed.\n"),
+                       rtc_dev_name);
+-              exit(EX_IOERR);
++              audit_exit(EX_IOERR);
+       }
+       if (debug)
diff --git a/util-linux-audit-login.patch b/util-linux-audit-login.patch
new file mode 100644 (file)
index 0000000..97f4efb
--- /dev/null
@@ -0,0 +1,103 @@
+- add audit message to login
+
+diff -ur util-linux-2.13-pre4.orig/login-utils/login.c util-linux-2.13-pre4/login-utils/login.c
+--- util-linux-2.13-pre4.orig/login-utils/login.c      2005-10-14 13:59:08.000000000 -0400
++++ util-linux-2.13-pre4/login-utils/login.c   2005-10-14 15:43:54.000000000 -0400
+@@ -106,6 +106,7 @@
+ #include <sys/syslog.h>
+ #include <sys/sysmacros.h>
+ #include <netdb.h>
++#include <libaudit.h>
+ #include "pathnames.h"
+ #include "my_crypt.h"
+ #include "login.h"
+@@ -329,6 +330,7 @@
+ #ifdef LOGIN_CHOWN_VCS
+     char vcsn[20], vcsan[20];
+ #endif
++    int audit_fd;
+     pid = getpid();
+@@ -545,11 +547,25 @@
+              (retcode == PAM_USER_UNKNOWN) ||
+              (retcode == PAM_CRED_INSUFFICIENT) ||
+              (retcode == PAM_AUTHINFO_UNAVAIL))) {
++          struct passwd *pw;
++          char buf[64];
+           pam_get_item(pamh, PAM_USER, (const void **) &username);
+           syslog(LOG_NOTICE,_("FAILED LOGIN %d FROM %s FOR %s, %s"),
+                  failcount, hostname, username, pam_strerror(pamh, retcode));
+           logbtmp(tty_name, username, hostname);
++          audit_fd = audit_open();
++          pw = getpwnam(username);
++          if (pw) {
++              snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
++              audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, 
++                      buf, hostname, NULL, tty_name, 0);
++          } else {
++              snprintf(buf, sizeof(buf), "acct=%s", username);
++              audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, 
++                      buf, hostname, NULL, tty_name, 0);
++          }
++          close(audit_fd);
+           fprintf(stderr,_("Login incorrect\n\n"));
+           pam_set_item(pamh,PAM_USER,NULL);
+@@ -557,6 +573,8 @@
+       }
+       if (retcode != PAM_SUCCESS) {
++          struct passwd *pw;
++          char buf[64];
+           pam_get_item(pamh, PAM_USER, (const void **) &username);
+           if (retcode == PAM_MAXTRIES)
+@@ -567,6 +585,18 @@
+               syslog(LOG_NOTICE,_("FAILED LOGIN SESSION FROM %s FOR %s, %s"),
+                       hostname, username, pam_strerror(pamh, retcode));
+           logbtmp(tty_name, username, hostname);
++          audit_fd = audit_open();
++          pw = getpwnam(username);
++          if (pw) {
++              snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid);
++              audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, 
++                      buf, hostname, NULL, tty_name, 0);
++          } else {
++              snprintf(buf, sizeof(buf), "acct=%s", username);
++              audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, 
++                      buf, hostname, NULL, tty_name, 0);
++          }
++          close(audit_fd);
+           fprintf(stderr,_("\nLogin incorrect\n"));
+           pam_end(pamh, retcode);
+@@ -908,6 +938,15 @@
+ #endif
+ #endif
+     }
++
++    {
++      char buf[32];
++      audit_fd = audit_open();
++      snprintf(buf, sizeof(buf), "uid=%d", pwd->pw_uid);
++      audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, 
++              buf, hostname, NULL, tty_name, 1);
++      close(audit_fd);
++    }
+     
+     dolastlog(quietlog);
+     
+diff -ur util-linux-2.13-pre4.orig/login-utils/Makefile.am util-linux-2.13-pre4/login-utils/Makefile.am
+--- util-linux-2.13-pre4.orig/login-utils/Makefile.am  2005-10-14 13:59:08.000000000 -0400
++++ util-linux-2.13-pre4/login-utils/Makefile.am       2005-10-14 15:45:22.000000000 -0400
+@@ -55,7 +55,7 @@
+ if HAVE_PAM
+ chfn_LDADD += -lpam -lpam_misc
+ chsh_LDADD += -lpam -lpam_misc
+-login_LDADD += -lpam -lpam_misc
++login_LDADD += -lpam -lpam_misc -laudit
+ login_SOURCES = login.c
+ else
+ login_SOURCES = login.c checktty.c
diff --git a/util-linux-chsh.patch b/util-linux-chsh.patch
new file mode 100644 (file)
index 0000000..9635a9e
--- /dev/null
@@ -0,0 +1,21 @@
+- chsh to /bin/sh leaves shell field of /etc/passwd blank
+
+--- util-linux-2.11y/login-utils/chsh.c.sopwith        Fri Sep  5 08:51:49 2003
++++ util-linux-2.11y/login-utils/chsh.c        Fri Sep  5 08:53:43 2003
+@@ -185,7 +185,6 @@
+       printf (_("Shell not changed.\n"));
+       return 0;
+     }
+-    if (!strcmp(shell, "/bin/sh")) shell = "";
+     pw->pw_shell = shell;
+     if (setpwnam (pw) < 0) {
+       perror ("setpwnam");
+@@ -299,6 +298,8 @@
+ check_shell (char *shell) {
+     int i, c;
++    if (! *shell) shell = "/bin/sh"; /* Fudge it */
++
+     if (*shell != '/') {
+       printf (_("%s: shell must be a full path name.\n"), whoami);
+       return (-1);
diff --git a/util-linux-col-EILSEQ.patch b/util-linux-col-EILSEQ.patch
new file mode 100644 (file)
index 0000000..e3989cc
--- /dev/null
@@ -0,0 +1,40 @@
+- col truncates data
+
+--- util-linux-2.13-pre6/text-utils/col.c.kzak 2002-03-09 00:05:12.000000000 +0100
++++ util-linux-2.13-pre6/text-utils/col.c      2006-02-21 22:25:48.000000000 +0100
+@@ -128,6 +128,7 @@
+       int this_line;                  /* line l points to */
+       int nflushd_lines;              /* number of lines that were flushed */
+       int adjust, opt, warned;
++      int ret = 0;
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+@@ -175,8 +176,16 @@
+       cur_line = max_line = nflushd_lines = this_line = 0;
+       cur_set = last_set = CS_NORMAL;
+       lines = l = alloc_line();
+-
+-      while ((ch = getwchar()) != WEOF) {
++      
++      while (feof(stdin)==0) {
++              errno = 0;
++              if ((ch = getwchar()) == WEOF) {
++                      if (errno==EILSEQ) {
++                              perror("col");
++                              ret = 1;
++                      }
++                      break;
++              }       
+               if (!iswgraph(ch)) {
+                       switch (ch) {
+                       case BS:                /* can't go back further */
+@@ -332,7 +341,7 @@
+       flush_blanks();
+       if (ferror(stdout) || fclose(stdout))
+               return 1;
+-      return 0;
++      return ret;
+ }
+ void flush_lines(int nflush)
diff --git a/util-linux-cramfs-maxentries.patch b/util-linux-cramfs-maxentries.patch
new file mode 100644 (file)
index 0000000..5b91588
--- /dev/null
@@ -0,0 +1,49 @@
+- mkfs.cramfs dies creating Fedora installer image
+
+--- util-linux-2.13-pre5/disk-utils/mkfs.cramfs.c.maxentries   2005-10-20 23:46:19.000000000 +0200
++++ util-linux-2.13-pre5/disk-utils/mkfs.cramfs.c      2005-10-20 23:54:07.000000000 +0200
+@@ -471,11 +471,13 @@
+  * entries, using a stack to remember the directories
+  * we've seen.
+  */
+-#define MAXENTRIES (100)
+ static unsigned int write_directory_structure(struct entry *entry, char *base, unsigned int offset)
+ {
+       int stack_entries = 0;
+-      struct entry *entry_stack[MAXENTRIES];
++      int stack_size = 64;
++      struct entry **entry_stack;
++
++      entry_stack = xmalloc(stack_size * sizeof(struct entry *));
+       for (;;) {
+               int dir_start = stack_entries;
+@@ -508,13 +510,13 @@
+                       if (verbose)
+                               printf("  %s\n", entry->name);
+                       if (entry->child) {
+-                              if (stack_entries >= MAXENTRIES) {
+-                                      fprintf(stderr,
+-                                              _("Exceeded MAXENTRIES.  Raise"
+-                                                " this value in mkcramfs.c "
+-                                                "and recompile.  Exiting.\n")
+-                                              );
+-                                      exit(8);
++                              if (stack_entries >= stack_size) {
++                                      stack_size *= 2;
++                                      entry_stack = realloc(entry_stack, stack_size * sizeof(struct entry *));
++                                      if (!entry_stack) {
++                                              perror(NULL);
++                                              exit(8);        /* out of memory */
++                                      }
+                               }
+                               entry_stack[stack_entries] = entry;
+                               stack_entries++;
+@@ -551,6 +553,7 @@
+                       printf("'%s':\n", entry->name);
+               entry = entry->child;
+       }
++      free(entry_stack);
+       return offset;
+ }
diff --git a/util-linux-cramfs-zerofiles.patch b/util-linux-cramfs-zerofiles.patch
new file mode 100644 (file)
index 0000000..9b96bea
--- /dev/null
@@ -0,0 +1,13 @@
+- mkfs.cramfs doesn't work correctly with empty files
+
+--- util-linux-2.13-pre5/disk-utils/mkfs.cramfs.c.zerofiles    2005-11-07 13:05:27.000000000 +0100
++++ util-linux-2.13-pre5/disk-utils/mkfs.cramfs.c      2005-11-07 13:06:38.000000000 +0100
+@@ -661,7 +661,7 @@
+                         if (e->same) {
+                                 set_data_offset(e, base, e->same->offset);
+                                 e->offset = e->same->offset;
+-                        } else {
++                        } else if (e->size) {
+                                 set_data_offset(e, base, offset);
+                                 e->offset = offset;
+                                 offset = do_compress(base, offset, e->name,
diff --git a/util-linux-ctrlaltdel-man.patch b/util-linux-ctrlaltdel-man.patch
new file mode 100644 (file)
index 0000000..02f48b8
--- /dev/null
@@ -0,0 +1,12 @@
+- Non-existant simpleinit(8) mentioned in ctrlaltdel(8)
+
+--- util-linux-2.13-pre6/sys-utils/ctrlaltdel.8.kzak   2006-08-10 12:23:53.000000000 +0200
++++ util-linux-2.13-pre6/sys-utils/ctrlaltdel.8        2006-08-10 12:24:08.000000000 +0200
+@@ -32,7 +32,6 @@
+ .SH FILES
+ .I /etc/rc.local
+ .SH "SEE ALSO"
+-.BR simpleinit (8),
+ .BR init (8)
+ .SH AUTHOR
+ Peter Orbaek (poe@daimi.aau.dk)
diff --git a/util-linux-ctty3.patch b/util-linux-ctty3.patch
new file mode 100644 (file)
index 0000000..5ac0c03
--- /dev/null
@@ -0,0 +1,106 @@
+The login program (which allows users to gain access to the system) does
+not handle signals correctly, causing some programs to stay running after
+the user has logged out.
+
+--- util-linux-2.13-pre1/login-utils/login.c.ctty3     2005-08-02 18:10:24.000000000 +0200
++++ util-linux-2.13-pre1/login-utils/login.c   2005-08-15 15:51:35.000000000 +0200
+@@ -285,7 +285,21 @@
+       updwtmp(_PATH_BTMP, &ut);
+ #endif
+ }
+-#endif        /* HAVE_SECURITY_PAM_MISC_H */
++
++static int childPid = 0;
++static volatile int got_sig = 0;
++
++static void
++parent_sig_handler(int signal)
++{
++      if(childPid)
++              kill(-childPid, signal);
++      else
++              got_sig = 1;
++      if(signal == SIGTERM)
++              kill(-childPid, SIGHUP); /* because the shell often ignores SIGTERM */
++}
++#endif  /* HAVE_SECURITY_PAM_MISC_H */
+ int
+ main(int argc, char **argv)
+@@ -307,7 +321,7 @@
+     int retcode;
+     pam_handle_t *pamh = NULL;
+     struct pam_conv conv = { misc_conv, NULL };
+-    pid_t childPid;
++    struct sigaction sa, oldsa_hup, oldsa_term;
+ #else
+     char *salt, *pp;
+ #endif
+@@ -1023,7 +1037,18 @@
+      * We must fork before setuid() because we need to call
+      * pam_close_session() as root.
+      */
++    memset(&sa, 0, sizeof(sa));
++    sa.sa_handler = SIG_IGN;
++    sigaction(SIGINT, &sa, NULL);
++
++    sigaction(SIGHUP, &sa, &oldsa_hup); /* ignore while we detach from the tty */
++    ioctl(0, TIOCNOTTY, NULL);
++
++    sa.sa_handler = parent_sig_handler;
++    sigaction(SIGHUP, &sa, NULL);
++    sigaction(SIGTERM, &sa, &oldsa_term);
+     
++    closelog();
+     childPid = fork();
+     if (childPid < 0) {
+        int errsv = errno;
+@@ -1034,19 +1059,20 @@
+     }
+     if (childPid) {
+-       /* parent - wait for child to finish, then cleanup session */
+-       signal(SIGHUP, SIG_IGN);
+-       signal(SIGINT, SIG_IGN);
+-       signal(SIGQUIT, SIG_IGN);
+-       signal(SIGTSTP, SIG_IGN);
+-       signal(SIGTTIN, SIG_IGN);
+-       signal(SIGTTOU, SIG_IGN);
+-
+-       wait(NULL);
++       close(0); close(1); close(2); 
++       sa.sa_handler = SIG_IGN;
++       sigaction(SIGQUIT, &sa, NULL);
++       sigaction(SIGINT, &sa, NULL);
++       while(wait(NULL) == -1 && errno == EINTR) /**/ ;
++       openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
+        PAM_END;
+        exit(0);
+     }
++    sigaction(SIGHUP, &oldsa_hup, NULL);
++    sigaction(SIGTERM, &oldsa_term, NULL);
++    if(got_sig) exit(1);
++
+     /* child */
+     /*
+      * Problem: if the user's shell is a shell like ash that doesnt do
+@@ -1058,14 +1084,15 @@
+     setsid();
+     /* make sure we have a controlling tty */
+-    opentty(ttyn);
+     openlog("login", LOG_ODELAY, LOG_AUTHPRIV);       /* reopen */
+     /*
+      * TIOCSCTTY: steal tty from other process group.
+      */
+-    if (ioctl(0, TIOCSCTTY, 1))
+-          syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
++    if (ioctl(0, TIOCSCTTY, (char *)1)) {
++          syslog(LOG_ERR, _("Couldn't set controlling terminal: %s"), strerror(errno));
++          exit(1);
++    }
+ #endif
+     signal(SIGINT, SIG_DFL);
+     
diff --git a/util-linux-execl.patch b/util-linux-execl.patch
new file mode 100644 (file)
index 0000000..d80c939
--- /dev/null
@@ -0,0 +1,27 @@
+- NULL is better than zero at end of execl()
+
+--- util-linux-2.12p/login-utils/agetty.c.execl        2005-07-12 15:53:25.000000000 +0200
++++ util-linux-2.12p/login-utils/agetty.c      2005-07-12 15:53:49.000000000 +0200
+@@ -382,7 +382,7 @@
+     /* Let the login program take care of password validation. */
+-    (void) execl(options.login, options.login, "--", logname, (char *) 0);
++    (void) execl(options.login, options.login, "--", logname, NULL);
+     error(_("%s: can't exec %s: %m"), options.tty, options.login);
+     exit(0);  /* quiet GCC */
+ }
+--- util-linux-2.12p/misc-utils/script.c.execl 2005-07-12 15:54:17.000000000 +0200
++++ util-linux-2.12p/misc-utils/script.c       2005-07-12 15:54:28.000000000 +0200
+@@ -325,9 +325,9 @@
+               shname = shell;
+       if (cflg)
+-              execl(shell, shname, "-c", cflg, 0);
++              execl(shell, shname, "-c", cflg, NULL);
+       else
+-              execl(shell, shname, "-i", 0);
++              execl(shell, shname, "-i", NULL);
+       perror(shell);
+       fail();
diff --git a/util-linux-fdformat-ide.patch b/util-linux-fdformat-ide.patch
new file mode 100644 (file)
index 0000000..80ea0b6
--- /dev/null
@@ -0,0 +1,22 @@
+--- util-linux-2.12p/disk-utils/fdformat.8.ide 2005-04-25 11:39:19.528340384 +0200
++++ util-linux-2.12p/disk-utils/fdformat.8     2005-04-25 11:44:07.189609224 +0200
+@@ -45,6 +45,10 @@
+ .BR setfdprm (8)
+ to load the disk parameters.
++For ATAPI IDE floppy driver (also known as LS-120 drives or "Superdisk"
++drives) you have to use the 
++.BR floppy (8).
++
+ .SH OPTIONS
+ .TP
+ .B \-n
+@@ -54,6 +58,7 @@
+ .BR fd (4),
+ .BR setfdprm (8),
+ .BR mkfs (8),
+-.BR emkfs (8)
++.BR emkfs (8),
++.BR floppy (8)
+ .SH AUTHOR
+ Werner Almesberger (almesber@nessie.cs.id.ethz.ch)
diff --git a/util-linux-fdisk-b-4096.patch b/util-linux-fdisk-b-4096.patch
new file mode 100644 (file)
index 0000000..b2dde20
--- /dev/null
@@ -0,0 +1,15 @@
+
+ The "-b" option allows to manually define size of sector size. We need to support
+ 4096 bytes for really huge disks. [kzak 12/14/2006]
+--- util-linux-2.13-pre7/fdisk/fdisk.c.kzak    2006-12-14 10:21:57.000000000 +0100
++++ util-linux-2.13-pre7/fdisk/fdisk.c 2006-12-14 10:22:21.000000000 +0100
+@@ -2491,7 +2491,7 @@
+                       */
+                       sector_size = atoi(optarg);
+                       if (sector_size != 512 && sector_size != 1024 &&
+-                          sector_size != 2048)
++                          sector_size != 2048 && sector_size != 4096)
+                               fatal(usage);
+                       sector_offset = 2;
+                       user_set_sector_size = 1;
diff --git a/util-linux-fdisk-gpt.patch b/util-linux-fdisk-gpt.patch
new file mode 100644 (file)
index 0000000..3476e71
--- /dev/null
@@ -0,0 +1,495 @@
+- sfdisk warning for large partitions, gpt
+
+--- util-linux-2.13-pre6/fdisk/fdisk.c.gpt     2005-11-24 15:30:36.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/fdisk.c 2005-11-24 15:30:36.000000000 +0100
+@@ -34,6 +34,8 @@
+ #include <linux/blkpg.h>
+ #endif
++#include "gpt.h"
++
+ static void delete_partition(int i);
+ #define hex_val(c)    ({ \
+@@ -2400,6 +2402,14 @@
+ }
+ static void
++gpt_warning(char *dev)
++{
++      if (gpt_probe_signature_devname(dev))
++              fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
++                      "The util fdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
++}
++
++static void
+ try(char *device, int user_specified) {
+       int gb;
+@@ -2409,6 +2419,7 @@
+       if (!user_specified)
+               if (is_ide_cdrom_or_tape(device))
+                       return;
++      gpt_warning(device);
+       if ((fd = open(disk_device, type_open)) >= 0) {
+               gb = get_boot(try_only);
+               if (gb > 0) { /* I/O error */
+@@ -2470,6 +2481,8 @@
+       printf(_("%c: unknown command\n"), c);
+ }
++
++
+ int
+ main(int argc, char **argv) {
+       int j, c;
+@@ -2574,6 +2587,7 @@
+               for (j = optind; j < argc; j++) {
+                       disk_device = argv[j];
++                      gpt_warning(disk_device);
+                       if ((fd = open(disk_device, type_open)) < 0)
+                               fatal(unable_to_open);
+                       if (disksize(fd, &size))
+@@ -2594,6 +2608,7 @@
+       else
+               fatal(usage2);
++      gpt_warning(disk_device);
+       get_boot(fdisk);
+       if (osf_label) {
+--- /dev/null  2005-11-14 15:52:26.044616250 +0100
++++ util-linux-2.13-pre6/fdisk/gpt.h   2005-11-24 15:30:36.000000000 +0100
+@@ -0,0 +1,9 @@
++
++#ifndef __GPT_H__
++#define __GPT_H__
++
++extern int gpt_probe_signature_fd(int fd);
++extern int gpt_probe_signature_devname(char *devname);
++
++#endif /* __GPT_H__ */
++
+--- util-linux-2.13-pre6/fdisk/Makefile.am.gpt 2005-10-16 14:12:52.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/Makefile.am     2005-11-24 15:31:42.000000000 +0100
+@@ -5,13 +5,13 @@
+ sbin_PROGRAMS = fdisk
+ man_MANS = fdisk.8
+ fdisk_SOURCES = fdisk.c disksize.c fdiskbsdlabel.c fdisksgilabel.c \
+-      fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c
++      fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c gpt.c
+ if !SPARC
+ sbin_PROGRAMS += sfdisk
+ man_MANS += sfdisk.8
+-sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c
++sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c gpt.c
+ if USE_SLANG
+ sbin_PROGRAMS += cfdisk
+--- util-linux-2.13-pre6/fdisk/fdisk.8.gpt     2005-11-24 15:30:36.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/fdisk.8 2005-11-24 15:30:36.000000000 +0100
+@@ -42,6 +42,11 @@
+ partition tables.
+ It understands DOS type partition tables and BSD or SUN type disklabels.
++.B fdisk 
++doesn't understand GUID Partition Table (GPT) and 
++it is not designed for large partitions. In particular case use more advanced GNU 
++.B parted(8).
++
+ The
+ .I device
+ is usually one of the following:
+--- util-linux-2.13-pre6/fdisk/sfdisk.8.gpt    2004-12-31 17:28:30.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/sfdisk.8        2005-11-24 15:30:36.000000000 +0100
+@@ -18,6 +18,11 @@
+ on a device, check the partitions on a device, and - very dangerous -
+ repartition a device.
++.B sfdisk 
++doesn't understand GUID Partition Table (GPT) and 
++it is not designed for large partitions. In particular case use more advanced GNU 
++.B parted(8).
++
+ .SS "List Sizes"
+ .BI "sfdisk \-s " partition
+ gives the size of
+--- /dev/null  2005-11-14 15:52:26.044616250 +0100
++++ util-linux-2.13-pre6/fdisk/gpt.c   2005-11-24 15:30:36.000000000 +0100
+@@ -0,0 +1,287 @@
++/*
++    GPT (GUID Partition Table) signature detection. Based on libparted and 
++    util-linux/partx.
++  
++    Warning: this code doesn't do all GPT checks (CRC32, Protective MBR, ..). It's
++             really GPT signature detection only.
++    
++    -- Karel Zak <kzak@redhat.com> (Jun-2-2005)
++
++*/
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <inttypes.h>
++#include <sys/stat.h>
++#include <sys/ioctl.h>
++#include <sys/utsname.h>
++#include <sys/types.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <errno.h>
++#include <linux/fs.h>
++
++#include "gpt.h"
++
++#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
++#define SECTOR_SIZE   512     /* default */
++
++#define _GET_BYTE(x, n)               ( ((x) >> (8 * (n))) & 0xff )
++
++#define _PED_SWAP64(x)                ( (_GET_BYTE(x, 0) << 56)       \
++                              + (_GET_BYTE(x, 1) << 48)       \
++                              + (_GET_BYTE(x, 2) << 40)       \
++                              + (_GET_BYTE(x, 3) << 32)       \
++                              + (_GET_BYTE(x, 4) << 24)       \
++                              + (_GET_BYTE(x, 5) << 16)       \
++                              + (_GET_BYTE(x, 6) << 8)        \
++                              + (_GET_BYTE(x, 7) << 0) )
++
++#define PED_SWAP64(x)           ((uint64_t) _PED_SWAP64( (uint64_t) (x) ))
++
++#if __BYTE_ORDER == __LITTLE_ENDIAN
++# define CPU_TO_LE64(x)       (x)
++#else
++# define CPU_TO_LE64(x)       PED_SWAP64(x)
++#endif
++
++#define BLKSSZGET  _IO(0x12,104) /* get block device sector size */
++#define BLKGETLASTSECT  _IO(0x12,108)   /* get last sector of block device */
++#define BLKGETSIZE _IO(0x12,96)       /* return device size */
++#define BLKGETSIZE64 _IOR(0x12,114,size_t)    /* return device size in bytes (u64 *arg) */
++
++#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
++#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
++
++typedef struct {
++        uint32_t time_low;
++        uint16_t time_mid;
++        uint16_t time_hi_and_version;
++        uint8_t  clock_seq_hi_and_reserved;
++        uint8_t  clock_seq_low;
++        uint8_t  node[6];
++} /* __attribute__ ((packed)) */ efi_guid_t;
++/* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
++ * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
++ * data.  It turns out we don't need it in this case, so it doesn't break
++ * anything :)
++ */
++
++typedef struct _GuidPartitionTableHeader_t {
++      uint64_t Signature;
++      uint32_t Revision;
++      uint32_t HeaderSize;
++      uint32_t HeaderCRC32;
++      uint32_t Reserved1;
++      uint64_t MyLBA;
++      uint64_t AlternateLBA;
++      uint64_t FirstUsableLBA;
++      uint64_t LastUsableLBA;
++      efi_guid_t DiskGUID;
++      uint64_t PartitionEntryLBA;
++      uint32_t NumberOfPartitionEntries;
++      uint32_t SizeOfPartitionEntry;
++      uint32_t PartitionEntryArrayCRC32;
++      uint8_t Reserved2[512 - 92];
++} __attribute__ ((packed)) GuidPartitionTableHeader_t;
++
++struct blkdev_ioctl_param {
++        unsigned int block;
++        size_t content_length;
++        char * block_contents;
++};
++
++static int
++_get_linux_version (void)
++{
++      static int kver = -1;
++      struct utsname uts;
++      int major;
++      int minor;
++      int teeny;
++
++      if (kver != -1)
++              return kver;
++      if (uname (&uts))
++              return kver = 0;
++      if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) != 3)
++              return kver = 0;
++      return kver = KERNEL_VERSION (major, minor, teeny);
++}
++
++static unsigned int
++_get_sector_size (int fd)
++{
++      unsigned int sector_size;
++
++      if (_get_linux_version() < KERNEL_VERSION (2,3,0))
++              return SECTOR_SIZE;
++      if (ioctl (fd, BLKSSZGET, &sector_size))
++              return SECTOR_SIZE;
++      return sector_size;
++}
++
++static uint64_t
++_get_num_sectors(int fd)
++{
++      int version = _get_linux_version();
++      unsigned long   size;
++      uint64_t bytes=0;
++
++      if (version >= KERNEL_VERSION(2,5,4) || 
++              (version <  KERNEL_VERSION(2,5,0) && 
++               version >= KERNEL_VERSION (2,4,18)))
++      {
++                if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) 
++                        return bytes / _get_sector_size(fd);
++      }
++      if (ioctl (fd, BLKGETSIZE, &size))
++              return 0;
++      return size;
++}
++
++static uint64_t
++last_lba(int fd)
++{
++      int rc;
++      uint64_t sectors = 0;
++      struct stat s;
++
++      memset(&s, 0, sizeof (s));
++      rc = fstat(fd, &s);
++      if (rc == -1) 
++      {
++              fprintf(stderr, "last_lba() could not stat: %s\n",
++                      strerror(errno));
++              return 0;
++      }
++      if (S_ISBLK(s.st_mode))
++              sectors = _get_num_sectors(fd);
++      else 
++      {
++              fprintf(stderr,
++                      "last_lba(): I don't know how to handle files with mode %x\n",
++                      s.st_mode);
++              sectors = 1;
++      }
++      return sectors - 1;
++}
++
++static ssize_t
++read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
++{
++        int rc;
++        struct blkdev_ioctl_param ioctl_param;
++
++        if (!buffer) return 0; 
++
++        ioctl_param.block = 0; /* read the last sector */
++        ioctl_param.content_length = count;
++        ioctl_param.block_contents = buffer;
++
++        rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
++        if (rc == -1) perror("read failed");
++
++        return !rc;
++}
++
++static ssize_t
++read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
++{
++      int sector_size = _get_sector_size(fd);
++      off_t offset = lba * sector_size;
++        ssize_t bytesread;
++
++      lseek(fd, offset, SEEK_SET);
++      bytesread = read(fd, buffer, bytes);
++
++        /* Kludge.  This is necessary to read/write the last
++           block of an odd-sized disk, until Linux 2.5.x kernel fixes.
++           This is only used by gpt.c, and only to read
++           one sector, so we don't have to be fancy.
++        */
++        if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd))
++                bytesread = read_lastoddsector(fd, lba, buffer, bytes);
++        return bytesread;
++}
++
++static GuidPartitionTableHeader_t *
++alloc_read_gpt_header(int fd, uint64_t lba)
++{
++      GuidPartitionTableHeader_t *gpt = 
++              (GuidPartitionTableHeader_t *) malloc(sizeof (GuidPartitionTableHeader_t));
++      if (!gpt)
++              return NULL;
++      memset(gpt, 0, sizeof (*gpt));
++      if (!read_lba(fd, lba, gpt, sizeof (GuidPartitionTableHeader_t))) 
++      {
++              free(gpt);
++              return NULL;
++      }
++      return gpt;
++}
++
++static int
++gpt_check_signature(int fd, uint64_t lba)
++{
++      GuidPartitionTableHeader_t *gpt;
++      int res=0;
++
++      if ((gpt = alloc_read_gpt_header(fd, lba)))
++      {
++              if (gpt->Signature == CPU_TO_LE64(GPT_HEADER_SIGNATURE))
++                      res = 1;
++              free(gpt);
++      }
++      return res;
++}
++
++/* returns:
++ *    0 not found GPT
++ *    1 for valid primary GPT header
++ *    2 for valid alternative GPT header
++ */
++int
++gpt_probe_signature_fd(int fd)
++{
++      int res = 0;
++
++      /* check primary GPT header */  
++      if (gpt_check_signature(fd, GPT_PRIMARY_PARTITION_TABLE_LBA))
++              res = 1;
++      else
++      {
++              /* check alternative GPT header */
++              uint64_t lastlba = last_lba(fd);
++              if (gpt_check_signature(fd, lastlba))
++                      res = 2;
++      }
++      return res;
++}
++
++int
++gpt_probe_signature_devname(char *devname)
++{
++      int res, fd;
++      if ((fd = open(devname, O_RDONLY)) < 0)
++              return 0;
++      res = gpt_probe_signature_fd(fd);
++      close(fd);
++      return res;
++}
++
++#ifdef GPT_TEST_MAIN
++int
++main(int argc, char **argv)
++{
++      if (argc!=2)
++      {
++              fprintf(stderr, "usage: %s <dev>\n", argv[0]);
++              exit(EXIT_FAILURE);
++      }
++      if (gpt_probe_signature_devname(argv[1]))
++              printf("GPT (GUID Partition Table) detected on %s\n", argv[1]);
++      exit(EXIT_SUCCESS);
++}
++#endif
+--- util-linux-2.13-pre6/fdisk/sfdisk.c.gpt    2005-10-16 14:18:32.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/sfdisk.c        2005-11-24 15:30:36.000000000 +0100
+@@ -50,6 +50,8 @@
+ #include "nls.h"
+ #include "common.h"
++#include "gpt.h"
++
+ #define SIZE(a)       (sizeof(a)/sizeof(a[0]))
+ /*
+@@ -2457,6 +2459,23 @@
+       return NULL;
+ }     
++static void
++gpt_warning(char *dev, int warn_only)
++{
++      if (force)
++              warn_only = 1;
++      
++      if (gpt_probe_signature_devname(dev)) {
++              fflush(stdout);
++              fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
++                      "The util sfdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
++              if (!warn_only) {
++                      fprintf(stderr, _("Use the --force flag to overrule this check.\n"));
++                      exit(1);
++              }
++      }
++}
++
+ static void do_list(char *dev, int silent);
+ static void do_size(char *dev, int silent);
+ static void do_geom(char *dev, int silent);
+@@ -2602,6 +2621,7 @@
+       while ((dev = nextproc()) != NULL) {
+           if (is_ide_cdrom_or_tape(dev))
+               continue;
++          gpt_warning(dev, 1);
+           if (opt_out_geom)
+               do_geom(dev, 1);
+           if (opt_out_pt_geom)
+@@ -2629,6 +2649,7 @@
+     if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
+       while (optind < argc) {
++          gpt_warning(argv[optind], 1);
+           if (opt_out_geom)
+             do_geom(argv[optind], 0);
+           if (opt_out_pt_geom)
+@@ -2657,6 +2678,7 @@
+         fatal(_("usage: sfdisk --change-id device partition-number Id\n"));
+       else if (optind != argc-3 && optind != argc-2)
+         fatal(_("usage: sfdisk --id device partition-number [Id]\n"));
++      gpt_warning(argv[optind], 0);
+       do_change_id(argv[optind], argv[optind+1],
+                    (optind == argc-2) ? 0 : argv[optind+2]);
+       exit(exit_status);
+@@ -2666,6 +2688,8 @@
+       fatal(_("can specify only one device (except with -l or -s)\n"));
+     dev = argv[optind];
++    gpt_warning(dev, 0);
++    
+     if (opt_reread)
+       do_reread(dev);
+     else if (restore_sector_file)
+@@ -2842,6 +2866,8 @@
+     z = &oldp;
++    gpt_warning(dev, 0);
++    
+     rw = (!no_write && (arg || ac > 1));
+     fd = my_open(dev, rw, 0);
+@@ -2943,6 +2969,8 @@
+     z = &oldp;
++    gpt_warning(dev, 0);
++    
+     rw = !no_write;
+     fd = my_open(dev, rw, 0);
diff --git a/util-linux-fdisk-isfull.patch b/util-linux-fdisk-isfull.patch
new file mode 100644 (file)
index 0000000..4485a4c
--- /dev/null
@@ -0,0 +1,106 @@
+- fdisk -l inside xen guest shows no disks
+- "sfdisk -l" tries to open partitions
+
+--- util-linux-2.13-pre6/fdisk/sfdisk.c.isfull 2006-06-12 13:31:46.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/sfdisk.c        2006-06-12 13:31:47.000000000 +0200
+@@ -2413,19 +2413,6 @@
+       return is_ide;
+ }
+-static int
+-is_probably_full_disk(char *name) {
+-      struct hd_geometry geometry;
+-      int fd, i = 0;
+-
+-      fd = open(name, O_RDONLY);
+-      if (fd >= 0) {
+-              i = ioctl(fd, HDIO_GETGEO, &geometry);
+-              close(fd);
+-      }
+-      return (fd >= 0 && i == 0 && geometry.start == 0);
+-}
+-
+ #define PROC_PARTITIONS       "/proc/partitions"
+ static FILE *procf = NULL;
+--- util-linux-2.13-pre6/fdisk/common.h.isfull 2004-09-06 20:07:11.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/common.h        2006-06-12 13:31:47.000000000 +0200
+@@ -28,5 +28,6 @@
+ extern struct systypes i386_sys_types[];
+ extern char *partname(char *dev, int pno, int lth);
++extern int is_probably_full_disk(char *name);
+ int disksize(int fd, unsigned long long *sectors);
+--- util-linux-2.13-pre6/fdisk/partname.c.isfull       2002-07-07 14:16:43.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/partname.c      2006-06-12 13:32:54.000000000 +0200
+@@ -1,6 +1,9 @@
+ #include <ctype.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
+ #include "common.h"
+ /*
+@@ -45,3 +48,30 @@
+ partname(char *dev, int pno, int lth) {
+       return partnamebf(dev, pno, lth, 0, NULL);
+ }
++
++int
++is_probably_full_disk(char *name) {
++#ifdef HDIO_GETGEO
++      struct hd_geometry geometry;
++      int fd, i = 0;
++
++      fd = open(name, O_RDONLY);
++      if (fd >= 0) {
++              i = ioctl(fd, HDIO_GETGEO, &geometry);
++              close(fd);
++      }
++      if (i==0)
++              return (fd >= 0 && geometry.start == 0);
++      /*
++       * "silly heuristic" is still so sexy for us, because
++       * for example Xen doesn't implement HDIO_GETGEO for virtual
++       * block devices (/dev/xvda).
++       * -- kzak@redhat.com (23-Feb-2006)
++       */
++#endif
++      /* silly heuristic */
++      while (*name)
++              name++;
++      return !isdigit(name[-1]);
++}
++
+--- util-linux-2.13-pre6/fdisk/fdisk.c.isfull  2006-06-12 13:31:47.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/fdisk.c 2006-06-12 13:31:47.000000000 +0200
+@@ -788,26 +788,6 @@
+ #endif
+ }
+-static int
+-is_probably_full_disk(char *name) {
+-#ifdef HDIO_GETGEO
+-      struct hd_geometry geometry;
+-      int fd, i = 0;
+-
+-      fd = open(name, O_RDONLY);
+-      if (fd >= 0) {
+-              i = ioctl(fd, HDIO_GETGEO, &geometry);
+-              close(fd);
+-      }
+-      return (fd >= 0 && i == 0 && geometry.start == 0);
+-#else
+-      /* silly heuristic */
+-      while (*name)
+-              name++;
+-      return !isdigit(name[-1]);
+-#endif
+-}
+-
+ static void
+ get_partition_table_geometry(void) {
+       unsigned char *bufp = MBRbuffer;
diff --git a/util-linux-fdisk-sectors.patch b/util-linux-fdisk-sectors.patch
new file mode 100644 (file)
index 0000000..1226f25
--- /dev/null
@@ -0,0 +1,347 @@
+- wrong number of sectors for large disks
+
+--- util-linux-2.13-pre6/fdisk/fdisk.h.sectors 2006-06-12 10:50:11.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/fdisk.h 2006-06-12 10:50:52.000000000 +0200
+@@ -81,8 +81,8 @@
+ #define SINGULAR 1
+ extern char *const str_units(int);
+-extern unsigned int get_start_sect(struct partition *p);
+-extern unsigned int get_nr_sects(struct partition *p);
++extern unsigned long long get_start_sect(struct partition *p);
++extern unsigned long long get_nr_sects(struct partition *p);
+ extern int osf_label;
+--- util-linux-2.13-pre6/fdisk/fdisksgilabel.h.sectors 2004-12-14 00:39:29.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/fdisksgilabel.h 2006-06-12 10:50:52.000000000 +0200
+@@ -103,8 +103,9 @@
+ /* fdisk.c */
+ #define sgilabel ((sgi_partition *)MBRbuffer)
+ #define sgiparam (sgilabel->devparam)
+-extern char MBRbuffer[MAX_SECTOR_SIZE];
+-extern unsigned int heads, sectors, cylinders, sector_size;
++extern unsigned char MBRbuffer[MAX_SECTOR_SIZE];
++extern unsigned int heads, cylinders, sector_size;
++extern unsigned long long sectors;
+ extern int show_begin;
+ extern int sgi_label;
+ extern char *partition_type(unsigned char type);
+--- util-linux-2.13-pre6/fdisk/fdisksunlabel.h.sectors 2004-12-14 00:39:18.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/fdisksunlabel.h 2006-06-12 10:50:52.000000000 +0200
+@@ -37,8 +37,9 @@
+                                : (__u32)(x))
+                                
+ /* fdisk.c */
+-extern char MBRbuffer[MAX_SECTOR_SIZE];
+-extern unsigned int heads, sectors, cylinders;
++extern unsigned char MBRbuffer[MAX_SECTOR_SIZE];
++extern unsigned int heads, cylinders;
++extern unsigned long long sectors;
+ extern int show_begin;
+ extern int sun_label;
+ extern char *partition_type(unsigned char type);
+--- util-linux-2.13-pre6/fdisk/fdiskaixlabel.h.sectors 2004-12-14 00:39:47.000000000 +0100
++++ util-linux-2.13-pre6/fdisk/fdiskaixlabel.h 2006-06-12 10:50:52.000000000 +0200
+@@ -19,9 +19,10 @@
+ /* fdisk.c */
+ #define aixlabel ((aix_partition *)MBRbuffer)
+-extern char MBRbuffer[MAX_SECTOR_SIZE];
++extern unsigned char MBRbuffer[MAX_SECTOR_SIZE];
+ extern char changed[MAXIMUM_PARTS];
+-extern unsigned int heads, sectors, cylinders;
++extern unsigned int heads, cylinders;
++extern unsigned long long sectors;
+ extern int show_begin;
+ extern int aix_label;
+ extern char *partition_type(unsigned char type);
+--- util-linux-2.13-pre6/fdisk/fdisksunlabel.c.sectors 2005-07-31 18:00:29.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/fdisksunlabel.c 2006-06-12 10:50:52.000000000 +0200
+@@ -348,7 +348,7 @@
+       }
+       snprintf(sunlabel->info, sizeof(sunlabel->info),
+-               "%s%s%s cyl %d alt %d hd %d sec %d", 
++               "%s%s%s cyl %d alt %d hd %d sec %llu", 
+                p ? p->vendor : "", (p && *p->vendor) ? " " : "",
+                p ? p->model
+                  : (floppy ? _("3,5\" floppy") : _("Linux custom")),
+@@ -655,7 +655,7 @@
+       w = strlen(disk_device);
+       if (xtra)
+               printf(
+-              _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n"
++              _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d rpm\n"
+               "%d cylinders, %d alternate cylinders, %d physical cylinders\n"
+               "%d extra sects/cyl, interleave %d:1\n"
+               "%s\n"
+@@ -669,7 +669,7 @@
+                      str_units(PLURAL), units_per_sector);
+       else
+               printf(
+-      _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n"
++      _("\nDisk %s (Sun disk label): %d heads, %llu sectors, %d cylinders\n"
+       "Units = %s of %d * 512 bytes\n\n"),
+                      disk_device, heads, sectors, cylinders,
+                      str_units(PLURAL), units_per_sector);
+--- util-linux-2.13-pre6/fdisk/fdisk.c.sectors 2006-06-12 10:50:11.000000000 +0200
++++ util-linux-2.13-pre6/fdisk/fdisk.c 2006-06-12 10:51:53.000000000 +0200
+@@ -64,7 +64,7 @@
+ /* A valid partition table sector ends in 0x55 0xaa */
+ static unsigned int
+-part_table_flag(char *b) {
++part_table_flag(unsigned char *b) {
+       return ((unsigned int) b[510]) + (((unsigned int) b[511]) << 8);
+ }
+@@ -74,7 +74,7 @@
+ }
+ static void
+-write_part_table_flag(char *b) {
++write_part_table_flag(unsigned char *b) {
+       b[510] = 0x55;
+       b[511] = 0xaa;
+ }
+@@ -101,17 +101,17 @@
+       store4_little_endian(p->start4, start_sect);
+ }
+-unsigned int
++unsigned long long
+ get_start_sect(struct partition *p) {
+       return read4_little_endian(p->start4);
+ }
+ static void
+-set_nr_sects(struct partition *p, unsigned int nr_sects) {
++set_nr_sects(struct partition *p, unsigned long long nr_sects) {
+       store4_little_endian(p->size4, nr_sects);
+ }
+-unsigned int
++unsigned long long
+ get_nr_sects(struct partition *p) {
+       return read4_little_endian(p->size4);
+ }
+@@ -123,7 +123,7 @@
+  * Raw disk label. For DOS-type partition tables the MBR,
+  * with descriptions of the primary partitions.
+  */
+-char MBRbuffer[MAX_SECTOR_SIZE];
++unsigned char MBRbuffer[MAX_SECTOR_SIZE];
+ /*
+  * per partition table entry data
+@@ -137,8 +137,8 @@
+       struct partition *part_table;   /* points into sectorbuffer */
+       struct partition *ext_pointer;  /* points into sectorbuffer */
+       char changed;                   /* boolean */
+-      unsigned int offset;            /* disk sector number */
+-      char *sectorbuffer;             /* disk sector contents */
++      unsigned long long offset;      /* disk sector number */
++      unsigned char *sectorbuffer;    /* disk sector contents */
+ } ptes[MAXIMUM_PARTS];
+ char  *disk_device,                   /* must be specified */
+@@ -157,15 +157,14 @@
+ unsigned int  pt_heads, pt_sectors;
+ unsigned int  kern_heads, kern_sectors;
++unsigned long long sector_offset = 1, extended_offset = 0, sectors;
++
+ unsigned int  heads,
+-      sectors,
+       cylinders,
+       sector_size = DEFAULT_SECTOR_SIZE,
+       user_set_sector_size = 0,
+-      sector_offset = 1,
+       units_per_sector = 1,
+-      display_in_cyl_units = 1,
+-      extended_offset = 0;            /* offset of link pointers */
++      display_in_cyl_units = 1;
+ unsigned long long total_number_of_sectors;
+@@ -242,21 +241,21 @@
+ }
+ static void
+-seek_sector(int fd, unsigned int secno) {
++seek_sector(int fd, unsigned long long secno) {
+       off_t offset = (off_t) secno * sector_size;
+       if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
+               fatal(unable_to_seek);
+ }
+ static void
+-read_sector(int fd, unsigned int secno, char *buf) {
++read_sector(int fd, unsigned long long secno, char *buf) {
+       seek_sector(fd, secno);
+       if (read(fd, buf, sector_size) != sector_size)
+               fatal(unable_to_read);
+ }
+ static void
+-write_sector(int fd, unsigned int secno, char *buf) {
++write_sector(int fd, unsigned long long secno, char *buf) {
+       seek_sector(fd, secno);
+       if (write(fd, buf, sector_size) != sector_size)
+               fatal(unable_to_write);
+@@ -264,11 +263,11 @@
+ /* Allocate a buffer and read a partition table sector */
+ static void
+-read_pte(int fd, int pno, unsigned int offset) {
++read_pte(int fd, int pno, unsigned long long offset) {
+       struct pte *pe = &ptes[pno];
+       pe->offset = offset;
+-      pe->sectorbuffer = (char *) malloc(sector_size);
++      pe->sectorbuffer = malloc(sector_size);
+       if (!pe->sectorbuffer)
+               fatal(out_of_memory);
+       read_sector(fd, offset, pe->sectorbuffer);
+@@ -276,7 +275,7 @@
+       pe->part_table = pe->ext_pointer = NULL;
+ }
+-static unsigned int
++static unsigned long long
+ get_partition_start(struct pte *pe) {
+       return pe->offset + get_start_sect(pe->part_table);
+ }
+@@ -542,10 +541,10 @@
+ }
+ static void
+-set_partition(int i, int doext, unsigned int start, unsigned int stop,
+-            int sysid) {
++set_partition(int i, int doext, unsigned long long start,
++            unsigned long long stop, int sysid) {
+       struct partition *p;
+-      unsigned int offset;
++      unsigned long long offset;
+       if (doext) {
+               p = ptes[i].ext_pointer;
+@@ -1544,7 +1543,7 @@
+       else
+               printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"),
+                      disk_device, megabytes/1000, (megabytes/100)%10, bytes);
+-      printf(_("%d heads, %d sectors/track, %d cylinders"),
++      printf(_("%d heads, %Ld sectors/track, %d cylinders"),
+              heads, sectors, cylinders);
+       if (units_per_sector == 1)
+               printf(_(", total %llu sectors"),
+@@ -1776,20 +1775,21 @@
+       struct partition *p;
+       int i;
+-      printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"),
++      printf(_("\nDisk %s: %d heads, %Ld sectors, %d cylinders\n\n"),
+               disk_device, heads, sectors, cylinders);
+         printf(_("Nr AF  Hd Sec  Cyl  Hd Sec  Cyl     Start      Size ID\n"));
+       for (i = 0 ; i < partitions; i++) {
+               pe = &ptes[i];
+               p = (extend ? pe->ext_pointer : pe->part_table);
+               if (p != NULL) {
+-                        printf("%2d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n",
++                        printf("%2d %02x%4d%4d%5d%4d%4d%5d%11lu%11lu %02x\n",
+                               i + 1, p->boot_ind, p->head,
+                               sector(p->sector),
+                               cylinder(p->sector, p->cyl), p->end_head,
+                               sector(p->end_sector),
+                               cylinder(p->end_sector, p->end_cyl),
+-                              get_start_sect(p), get_nr_sects(p), p->sys_ind);
++                              (unsigned long) get_start_sect(p),
++                              (unsigned long) get_nr_sects(p), p->sys_ind);
+                       if (p->sys_ind)
+                               check_consistency(p, i);
+               }
+@@ -1797,7 +1797,7 @@
+ }
+ static void
+-fill_bounds(unsigned int *first, unsigned int *last) {
++fill_bounds(unsigned long long *first, unsigned long long *last) {
+       int i;
+       struct pte *pe = &ptes[0];
+       struct partition *p;
+@@ -1830,7 +1830,7 @@
+                       n, h + 1, heads);
+       if (real_s >= sectors)
+               fprintf(stderr, _("Partition %d: sector %d greater than "
+-                      "maximum %d\n"), n, s, sectors);
++                      "maximum %Ld\n"), n, s, sectors);
+       if (real_c >= cylinders)
+               fprintf(stderr, _("Partitions %d: cylinder %d greater than "
+                       "maximum %d\n"), n, real_c + 1, cylinders);
+@@ -1843,8 +1843,8 @@
+ static void
+ verify(void) {
+       int i, j;
+-      unsigned int total = 1;
+-      unsigned int first[partitions], last[partitions];
++      unsigned long total = 1;
++      unsigned long long first[partitions], last[partitions];
+       struct partition *p;
+       if (warn_geometry())
+@@ -1888,7 +1888,7 @@
+       if (extended_offset) {
+               struct pte *pex = &ptes[ext_index];
+-              unsigned int e_last = get_start_sect(pex->part_table) +
++              unsigned long long e_last = get_start_sect(pex->part_table) +
+                       get_nr_sects(pex->part_table) - 1;
+               for (i = 4; i < partitions; i++) {
+@@ -1907,8 +1907,8 @@
+       }
+       if (total > total_number_of_sectors)
+-              printf(_("Total allocated sectors %d greater than the maximum "
+-                      "%lld\n"), total, total_number_of_sectors);
++              printf(_("Total allocated sectors %ld greater than the maximum"
++                      " %lld\n"), total, total_number_of_sectors);
+       else if (total < total_number_of_sectors)
+               printf(_("%lld unallocated sectors\n"),
+                      total_number_of_sectors - total);
+@@ -1921,7 +1921,7 @@
+       struct partition *p = ptes[n].part_table;
+       struct partition *q = ptes[ext_index].part_table;
+       long long llimit;
+-      unsigned int start, stop = 0, limit, temp,
++      unsigned long long start, stop = 0, limit, temp,
+               first[partitions], last[partitions];
+       if (p && p->sys_ind) {
+@@ -1967,7 +1967,7 @@
+               if (start > limit)
+                       break;
+               if (start >= temp+units_per_sector && read) {
+-                      printf(_("Sector %d is already allocated\n"), temp);
++                      printf(_("Sector %llu is already allocated\n"), temp);
+                       temp = start;
+                       read = 0;
+               }
+@@ -2225,14 +2225,14 @@
+ #define MAX_PER_LINE  16
+ static void
+-print_buffer(char pbuffer[]) {
++print_buffer(unsigned char pbuffer[]) {
+       int     i,
+               l;
+       for (i = 0, l = 0; i < sector_size; i++, l++) {
+               if (l == 0)
+                       printf("0x%03X:", i);
+-              printf(" %02X", (unsigned char) pbuffer[i]);
++              printf(" %02X", pbuffer[i]);
+               if (l == MAX_PER_LINE - 1) {
+                       printf("\n");
+                       l = -1;
diff --git a/util-linux-fdisksegv.patch b/util-linux-fdisksegv.patch
new file mode 100644 (file)
index 0000000..dccec58
--- /dev/null
@@ -0,0 +1,34 @@
+if all extended partitions are used up adding a new partition will also ask if
+you want to add a logical partition. Choosing this option makes fdisk segfault
+
+*** util-linux-2.11y/fdisk/fdisk.c.000 2003-09-08 14:47:41.000000000 +0200
+--- util-linux-2.11y/fdisk/fdisk.c     2003-09-08 15:01:42.000000000 +0200
+***************
+*** 2020,2028 ****
+       for (i = 0; i < 4; i++)
+               free_primary += !ptes[i].part_table->sys_ind;
+  
+!      if (!free_primary && partitions >= MAXIMUM_PARTS) {
+!              printf(_("The maximum number of partitions has been created\n"));
+!              return;
+       }
+  
+       if (!free_primary) {
+--- 2020,2036 ----
+       for (i = 0; i < 4; i++)
+               free_primary += !ptes[i].part_table->sys_ind;
+  
+!      // Fix to only add primary partition if all logical partions are used <leonardjo@hetnet.nl>
+!      if (partitions >= MAXIMUM_PARTS) {
+!              if (!free_primary) {
+!                      printf(_("The maximum number of partitions has been created\n"));
+!                      return;
+!              }
+!              else {
+!                      add_partition(get_partition(0, 4),
+!                                    LINUX_NATIVE);
+!                      return;
+!              }
+       }
+  
+       if (!free_primary) {
diff --git a/util-linux-hexdump-gcc.patch b/util-linux-hexdump-gcc.patch
new file mode 100644 (file)
index 0000000..f088147
--- /dev/null
@@ -0,0 +1,17 @@
+
+ gcc 4.1.0: "warning: memset used with constant zero length parameter; this
+ could be due to transposed parameters". So, fix it!
+ -- 03/30/2006 Karel Zak <kzak@redhat.com> 
+
+--- util-linux-2.13-pre7/text-utils/display.c.gcc      2006-03-31 10:44:50.000000000 +0200
++++ util-linux-2.13-pre7/text-utils/display.c  2006-03-31 10:45:22.000000000 +0200
+@@ -255,7 +255,8 @@
+                                       (void)printf("*\n");
+                               return(NULL);
+                       }
+-                      memset((char *)curp + nread, 0, need);
++                      if (need > 0)
++                              memset((char *)curp + nread, 0, need);
+                       eaddress = address + nread;
+                       return(curp);
+               }
diff --git a/util-linux-hotkeys.patch b/util-linux-hotkeys.patch
new file mode 100644 (file)
index 0000000..6c9b4cf
--- /dev/null
@@ -0,0 +1,46 @@
+- vipw asks for editing shadow in local language but only "Y" is accepted as yes
+
+--- util-linux-2.12j/po/ca.po.sopwith  2004-12-05 14:08:08.000000000 -0500
++++ util-linux-2.12j/po/ca.po  2004-12-10 13:10:52.411668785 -0500
+@@ -7183,7 +7183,7 @@
+ #: login-utils/vipw.c:354
+ #, c-format
+ msgid "Would you like to edit %s now [y/n]? "
+-msgstr "Desitgeu editar %s ara? [s/n] "
++msgstr "Desitgeu editar %s ara? [y/n] "
+ #: login-utils/wall.c:104
+ #, c-format
+--- util-linux-2.12j/po/da.po.sopwith  2004-12-05 14:08:09.000000000 -0500
++++ util-linux-2.12j/po/da.po  2004-12-10 13:09:50.382880759 -0500
+@@ -1470,7 +1470,7 @@
+ #: fdisk/cfdisk.c:1526
+ msgid "Do you wish to start with a zero table [y/N] ?"
+-msgstr "Vil du starte med nulstillet tabel [j/N] ?"
++msgstr "Vil du starte med nulstillet tabel [y/N] ?"
+ #: fdisk/cfdisk.c:1574
+ msgid "You specified more cylinders than fit on disk"
+--- util-linux-2.12j/po/nl.po.sopwith  2004-12-05 14:08:15.000000000 -0500
++++ util-linux-2.12j/po/nl.po  2004-12-10 13:09:50.390878282 -0500
+@@ -1493,7 +1493,7 @@
+ #: fdisk/cfdisk.c:1526
+ msgid "Do you wish to start with a zero table [y/N] ?"
+-msgstr "Wilt u met een lege tabel beginnen [j/N] ?"
++msgstr "Wilt u met een lege tabel beginnen [y/N] ?"
+ #: fdisk/cfdisk.c:1574
+ msgid "You specified more cylinders than fit on disk"
+--- util-linux-2.12j/po/pt_BR.po.sopwith       2004-12-05 14:08:15.000000000 -0500
++++ util-linux-2.12j/po/pt_BR.po       2004-12-10 13:11:47.560587674 -0500
+@@ -7161,7 +7161,7 @@
+ #: login-utils/vipw.c:354
+ #, c-format
+ msgid "Would you like to edit %s now [y/n]? "
+-msgstr "Você gostaria de editar %s agora [s/n]"
++msgstr "Você gostaria de editar %s agora [y/n]"
+ #: login-utils/wall.c:104
+ #, c-format
diff --git a/util-linux-ipcs-shmax.patch b/util-linux-ipcs-shmax.patch
new file mode 100644 (file)
index 0000000..ce004d5
--- /dev/null
@@ -0,0 +1,27 @@
+--- util-linux-2.13-pre4/sys-utils/ipcs.c.shmax        2005-10-18 17:04:42.000000000 +0200
++++ util-linux-2.13-pre4/sys-utils/ipcs.c      2005-10-18 17:31:28.000000000 +0200
+@@ -25,6 +25,7 @@
+ #include <time.h>
+ #include <pwd.h>
+ #include <grp.h>
++#include <unistd.h>
+ #include "nls.h"
+ /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
+@@ -280,8 +280,14 @@
+                       (unsigned long) shminfo.shmmni);
+               printf (_("max seg size (kbytes) = %lu\n"),
+                       (unsigned long) (shminfo.shmmax >> 10));
++              
++              /* max shmem = pagesize * shminfo.shmall / 1024
++               * 
++               * note: that "shminfo.shmall * getpagesize()" is greater than ULONG_MAX (32bit)
++               *       it means that better is "/" before "*" or use "long long"  
++               */
+-              printf (_("max total shared memory (pages) = %lu\n"),
+-                      (unsigned long) shminfo.shmall);
++              printf (_("max total shared memory (kbytes) = %lu\n"),
++                      getpagesize()/1024 * (unsigned long) shminfo.shmall);
+               printf (_("min seg size (bytes) = %lu\n"),
+                       (unsigned long) shminfo.shmmin);
+               return;
diff --git a/util-linux-ipcs-typo.patch b/util-linux-ipcs-typo.patch
new file mode 100644 (file)
index 0000000..3e74ab7
--- /dev/null
@@ -0,0 +1,14 @@
+--- util-linux-2.12p/sys-utils/ipcs.c.typo     2005-03-25 13:01:54.871752240 +0100
++++ util-linux-2.12p/sys-utils/ipcs.c  2005-03-25 13:02:43.745322328 +0100
+@@ -423,9 +423,9 @@
+               break;
+       case TIME:
+-              printf (_("------ Shared Memory Operation/Change Times --------\n"));
++              printf (_("------ Semaphore Operation/Change Times --------\n"));
+               printf (_("%-8s %-10s %-26.24s %-26.24s\n"),
+-                      _("shmid"),_("owner"),_("last-op"),_("last-changed"));
++                      _("semid"),_("owner"),_("last-op"),_("last-changed"));
+               break;
+       case PID:
diff --git a/util-linux-login-hang.patch b/util-linux-login-hang.patch
new file mode 100644 (file)
index 0000000..759c9ca
--- /dev/null
@@ -0,0 +1,23 @@
+- login will attempt to run if it has no read/write access to its terminal
+- login's timeout can fail - needs to call siginterrupt(SIGALRM,1)
+
+--- util-linux-2.13-pre2/login-utils/login.c.hang      2005-10-03 16:02:54.000000000 +0200
++++ util-linux-2.13-pre2/login-utils/login.c   2005-10-03 16:16:16.000000000 +0200
+@@ -223,7 +223,8 @@
+       if (lstat(ttyn, &statbuf)
+           || !S_ISCHR(statbuf.st_mode)
+-          || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))) {
++          || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))
++          || (access(ttyn, R_OK | W_OK) != 0)) {
+               syslog(LOG_ERR, _("FATAL: bad tty"));
+               sleep(1);
+               exit(1);
+@@ -332,6 +333,7 @@
+     pid = getpid();
+     signal(SIGALRM, timedout);
++    siginterrupt(SIGALRM,1);          /* we have to interrupt syscalls like ioclt() */
+     alarm((unsigned int)timeout);
+     signal(SIGQUIT, SIG_IGN);
+     signal(SIGINT, SIG_IGN);
diff --git a/util-linux-login-ipv6.patch b/util-linux-login-ipv6.patch
new file mode 100644 (file)
index 0000000..5d9d656
--- /dev/null
@@ -0,0 +1,82 @@
+- IPv6 support to login command
+
+--- util-linux-2.13-pre6/login-utils/login.c.ipv6      2006-10-12 10:10:34.000000000 +0200
++++ util-linux-2.13-pre6/login-utils/login.c   2006-10-12 10:17:16.000000000 +0200
+@@ -173,7 +173,7 @@
+ #ifdef HAVE_SECURITY_PAM_MISC_H
+ static struct passwd pwdcopy;
+ #endif
+-char    hostaddress[4];               /* used in checktty.c */
++char    hostaddress[16];      /* used in checktty.c */
+ char  *hostname;              /* idem */
+ static char   *username, *tty_name, *tty_number;
+ static char   thishost[100];
+@@ -281,7 +281,7 @@
+       if (hostname) {
+               xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
+               if (hostaddress[0])
+-                      memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr));
++                      memcpy(&ut.ut_addr_v6, hostaddress, sizeof(ut.ut_addr_v6));
+       }
+ #if HAVE_UPDWTMP              /* bad luck for ancient systems */
+       updwtmp(_PATH_BTMP, &ut);
+@@ -380,13 +380,33 @@
+         hostname = strdup(optarg);    /* strdup: Ambrose C. Li */
+         {
+-                struct hostent *he = gethostbyname(hostname);
++              struct addrinfo hints, *info = NULL;
++              
++              memset(&hints, '\0', sizeof(hints));
++              hints.ai_flags = AI_ADDRCONFIG;
++
++              hostaddress[0] = 0;
+-                /* he points to static storage; copy the part we use */
+-                hostaddress[0] = 0;
+-                if (he && he->h_addr_list && he->h_addr_list[0])
+-                        memcpy(hostaddress, he->h_addr_list[0],
+-                               sizeof(hostaddress));
++              if (getaddrinfo(hostname, NULL, &hints, &info)==0 && info)
++              {
++                      if (info->ai_family == AF_INET)
++                      {
++                          struct sockaddr_in *sa4;
++                          
++                          sa4 = (struct sockaddr_in *) info->ai_addr;
++                          memcpy(hostaddress, &(sa4->sin_addr), 
++                                          sizeof(sa4->sin_addr));
++                      }
++                      if (info->ai_family == AF_INET6)
++                      {
++                          struct sockaddr_in6 *sa6;
++                          
++                          sa6 = (struct sockaddr_in6 *) info->ai_addr;
++                          memcpy(hostaddress, &(sa6->sin6_addr), 
++                                          sizeof(sa6->sin6_addr));
++                      }
++                      freeaddrinfo(info);
++              }
+         }
+         break;
+         
+@@ -906,7 +926,7 @@
+       if (hostname) {
+               xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
+               if (hostaddress[0])
+-                      memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr));
++                      memcpy(&ut.ut_addr_v6, hostaddress, sizeof(ut.ut_addr_v6));
+       }
+       
+       pututline(&ut);
+--- util-linux-2.13-pre6/login-utils/login.h.ipv6      2005-08-02 14:01:18.000000000 +0200
++++ util-linux-2.13-pre6/login-utils/login.h   2006-10-12 10:10:34.000000000 +0200
+@@ -1,7 +1,7 @@
+ /* defined in login.c */
+ extern void badlogin(const char *s);
+ extern void sleepexit(int);
+-extern char hostaddress[4];
++extern char hostaddress[16];
+ extern char *hostname;
+ /* defined in checktty.c */
diff --git a/util-linux-login-lastlog.patch b/util-linux-login-lastlog.patch
new file mode 100644 (file)
index 0000000..cd1b4f7
--- /dev/null
@@ -0,0 +1,11 @@
+--- util-linux-2.12p/login-utils/login.c.login-lastlog 2005-03-24 13:26:06.516865128 +0100
++++ util-linux-2.12p/login-utils/login.c       2005-03-24 13:26:58.136017824 +0100
+@@ -1397,7 +1397,7 @@
+     struct lastlog ll;
+     int fd;
+     
+-    if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
++    if ((fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, 0)) >= 0) {
+       lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
+       if (!quiet) {
+           if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
diff --git a/util-linux-login-pam-acct.patch b/util-linux-login-pam-acct.patch
new file mode 100644 (file)
index 0000000..ec6ded5
--- /dev/null
@@ -0,0 +1,33 @@
+- login omits pam_acct_mgmt & pam_chauthtok when authentication is skipped
+
+--- util-linux-2.13-pre6/login-utils/login.c.acct      2006-02-22 21:43:03.000000000 +0100
++++ util-linux-2.13-pre6/login-utils/login.c   2006-02-22 21:57:55.000000000 +0100
+@@ -602,16 +602,22 @@
+           pam_end(pamh, retcode);
+           exit(0);
+       }
++    }
+-      retcode = pam_acct_mgmt(pamh, 0);
+-
+-      if(retcode == PAM_NEW_AUTHTOK_REQD) {
+-          retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+-      }
++    /*
++     * Authentication may be skipped (for example, during krlogin, rlogin, etc...), 
++     * but it doesn't mean that we can skip other account checks. The account 
++     * could be disabled or password expired (althought kerberos ticket is valid).
++     * -- kzak@redhat.com (22-Feb-2006)
++     */
++    retcode = pam_acct_mgmt(pamh, 0);
+-      PAM_FAIL_CHECK;
++    if(retcode == PAM_NEW_AUTHTOK_REQD) {
++        retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+     }
++    PAM_FAIL_CHECK;
++
+     /*
+      * Grab the user information out of the password file for future usage
+      * First get the username that we are actually using, though.
diff --git a/util-linux-login-timeval.patch b/util-linux-login-timeval.patch
new file mode 100644 (file)
index 0000000..2f8e46a
--- /dev/null
@@ -0,0 +1,49 @@
+
+On 64-bit platforms such as x86_64, glibc is usally built with 32-bit
+compatibilty for various structures. One of them is utmp.
+
+What this means is that gettimeofday(&ut.ut_tv, NULL) on x86_64 will
+end up overwriting the first parts of ut_addr_v6, leading to garbage
+in the utmp file.
+
+
+--- util-linux-2.13-pre6/login-utils/login.c.kzak      2006-08-10 11:38:33.000000000 +0200
++++ util-linux-2.13-pre6/login-utils/login.c   2006-08-10 11:38:49.000000000 +0200
+@@ -257,6 +257,7 @@
+ static void
+ logbtmp(const char *line, const char *username, const char *hostname) {
+       struct utmp ut;
++      struct timeval tv;
+       memset(&ut, 0, sizeof(ut));
+@@ -267,7 +268,9 @@
+       xstrncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ #if defined(_HAVE_UT_TV)          /* in <utmpbits.h> included by <utmp.h> */
+-      gettimeofday(&ut.ut_tv, NULL);
++      gettimeofday(&tv, NULL);
++      ut.ut_tv.tv_sec = tv.tv_sec;
++      ut.ut_tv.tv_usec = tv.tv_usec;
+ #else
+       {
+               time_t t;
+@@ -872,6 +875,7 @@
+     {
+       struct utmp ut;
+       struct utmp *utp;
++      struct timeval tv;
+       
+       utmpname(_PATH_UTMP);
+       setutent();
+@@ -911,7 +915,9 @@
+       strncpy(ut.ut_user, username, sizeof(ut.ut_user));
+       xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
+ #ifdef _HAVE_UT_TV            /* in <utmpbits.h> included by <utmp.h> */
+-      gettimeofday(&ut.ut_tv, NULL);
++      gettimeofday(&tv, NULL);
++      ut.ut_tv.tv_sec = tv.tv_sec;
++      ut.ut_tv.tv_usec = tv.tv_usec;
+ #else
+       {
+           time_t t;
diff --git a/util-linux-look-separator.patch b/util-linux-look-separator.patch
new file mode 100644 (file)
index 0000000..75bdc91
--- /dev/null
@@ -0,0 +1,18 @@
+- look - doesn't work with separators
+
+--- util-linux-2.12p/misc-utils/look.c.sep     2005-05-02 12:51:17.808227240 +0200
++++ util-linux-2.12p/misc-utils/look.c 2005-05-02 12:53:18.078943312 +0200
+@@ -327,9 +327,12 @@
+       /* copy, ignoring things that should be ignored */
+       p = comparbuf;
+       i = stringlen;
+-      while(s2 < s2end && *s2 != '\n' && i--) {
++      while(s2 < s2end && *s2 != '\n' && i) {
+               if (!dflag || isalnum(*s2))
++              {
+                       *p++ = *s2;
++                      i--;
++              }
+               s2++;
+       }
+       *p = 0;
diff --git a/util-linux-losetup-all.patch b/util-linux-losetup-all.patch
new file mode 100644 (file)
index 0000000..e511472
--- /dev/null
@@ -0,0 +1,162 @@
+- losetup missing option -a [new feature]
+
+--- util-linux-2.13-pre6/mount/losetup.8.all   2006-10-12 10:34:47.000000000 +0200
++++ util-linux-2.13-pre6/mount/losetup.8       2006-10-12 10:37:35.000000000 +0200
+@@ -9,6 +9,8 @@
+ .B losetup
+ .I loop_device
+ .sp
++.B losetup -a
++.sp
+ .in -5
+ Delete loop:
+ .sp
+@@ -66,6 +68,8 @@
+ .B \-e
+ option.)
+ .SH OPTIONS
++.IP \fB\-a\fP
++Show status of all loop devices.
+ .IP \fB\-d\fP
+ Detach the file or device associated with the specified loop device.
+ .IP "\fB\-E \fIencryption_type\fP"
+--- util-linux-2.13-pre6/mount/lomount.c.all   2004-12-20 23:11:04.000000000 +0100
++++ util-linux-2.13-pre6/mount/lomount.c       2006-10-12 10:29:55.000000000 +0200
+@@ -28,6 +28,8 @@
+ extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
+ extern void error (const char *fmt, ...);     /* idem */
++#define SIZE(a) (sizeof(a)/sizeof(a[0]))
++
+ #ifdef LOOP_SET_FD
+ static int
+@@ -128,6 +130,42 @@
+       close (fd);
+       return 1;
+ }
++
++static int
++show_used_loop_devices (void) {
++      char dev[20];
++      char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
++      int i, j, fd, permission = 0, somedev = 0;
++      struct stat statbuf;
++      struct loop_info loopinfo;
++
++      for (j = 0; j < SIZE(loop_formats); j++) {
++          for(i = 0; i < 256; i++) {
++              sprintf(dev, loop_formats[j], i);
++              if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
++                      somedev++;
++                      fd = open (dev, O_RDONLY);
++                      if (fd >= 0) {
++                              if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
++                                      show_loop(dev);
++                              close (fd);
++                              somedev++;
++                      } else if (errno == EACCES)
++                              permission++;
++                      continue; /* continue trying as long as devices exist */
++              }
++              break;
++          }
++      }
++
++      if (somedev==0 && permission) {
++              error(_("%s: no permission to look at /dev/loop#"), progname);
++              return 1;
++      }
++      return 0;
++}
++
++
+ #endif
+ int
+@@ -139,8 +177,6 @@
+               major(statbuf.st_rdev) == LOOPMAJOR);
+ }
+-#define SIZE(a) (sizeof(a)/sizeof(a[0]))
+-
+ char *
+ find_unused_loop_device (void) {
+       /* Just creating a device, say in /tmp, is probably a bad idea -
+@@ -403,12 +439,13 @@
+ static void
+ usage(void) {
+-      fprintf(stderr, _("usage:\n\
+-  %s loop_device                                       # give info\n\
+-  %s -d loop_device                                    # delete\n\
+-  %s -f                                                # find unused\n\
+-  %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"),
+-              progname, progname, progname, progname);
++      fprintf(stderr, _("usage:\n"
++  "  %1$s loop_device                                       # give info\n"
++  "  %1$s -d loop_device                                    # delete\n"
++  "  %1$s -f                                                # find unused\n"
++  "  %1$s -a                                                # list all used\n"
++  "  %1$s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"),
++              progname);
+       exit(1);
+ }
+@@ -442,7 +479,7 @@
+ int
+ main(int argc, char **argv) {
+       char *p, *offset, *encryption, *passfd, *device, *file;
+-      int delete, find, c;
++      int delete, find, c, all;
+       int res = 0;
+       int ro = 0;
+       int pfd = -1;
+@@ -452,7 +489,7 @@
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+-      delete = find = 0;
++      delete = find = all = 0;
+       off = 0;
+       offset = encryption = passfd = NULL;
+@@ -460,8 +497,11 @@
+       if ((p = strrchr(progname, '/')) != NULL)
+               progname = p+1;
+-      while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
++      while ((c = getopt(argc, argv, "ade:E:fo:p:v")) != -1) {
+               switch (c) {
++              case 'a':
++                      all = 1;
++                      break;
+               case 'd':
+                       delete = 1;
+                       break;
+@@ -489,17 +529,22 @@
+       if (argc == 1) {
+               usage();
+       } else if (delete) {
+-              if (argc != optind+1 || encryption || offset || find)
++              if (argc != optind+1 || encryption || offset || find || all)
+                       usage();
+       } else if (find) {
+-              if (argc < optind || argc > optind+1)
++              if (all || argc < optind || argc > optind+1)
++                      usage();
++      } else if (all) {
++              if (argc > 2)
+                       usage();
+       } else {
+               if (argc < optind+1 || argc > optind+2)
+                       usage();
+       }
+-      if (find) {
++      if (all)
++              return show_used_loop_devices();
++      else if (find) {
+               device = find_unused_loop_device();
+               if (device == NULL)
+                       return -1;
diff --git a/util-linux-losetup-deprecated.patch b/util-linux-losetup-deprecated.patch
new file mode 100644 (file)
index 0000000..73e45c0
--- /dev/null
@@ -0,0 +1,13 @@
+--- util-linux-2.13-pre6/mount/losetup.8.kzak  2006-10-12 10:39:39.000000000 +0200
++++ util-linux-2.13-pre6/mount/losetup.8       2006-10-12 10:40:04.000000000 +0200
+@@ -133,6 +133,10 @@
+ .fi
+ .SH RESTRICTION
+ DES encryption is painfully slow. On the other hand, XOR is terribly weak.
++
++Cryptoloop is deprecated and unmaintained in 2.6 kernels. Use dm-crypt. For
++more details see 
++.B cryptsetup(8).
+ .\" .SH AUTHORS
+ .\" .nf
+ .\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
diff --git a/util-linux-losetup-rdonly.patch b/util-linux-losetup-rdonly.patch
new file mode 100644 (file)
index 0000000..f71b69d
--- /dev/null
@@ -0,0 +1,49 @@
+- add -r option to losetup to create a read-only loop
+
+--- util-linux-2.13-pre6/mount/lomount.c.ronly 2006-11-01 14:14:14.000000000 +0100
++++ util-linux-2.13-pre6/mount/lomount.c       2006-11-01 15:01:52.000000000 +0100
+@@ -444,7 +444,8 @@
+   "  %1$s -d loop_device                                    # delete\n"
+   "  %1$s -f                                                # find unused\n"
+   "  %1$s -a                                                # list all used\n"
+-  "  %1$s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"),
++  "  %1$s -r                                                # read-only loop\n"
++  "  %1$s [-e encryption] [-o offset] [-r] {-f|loop_device} file # setup\n"),
+               progname);
+       exit(1);
+ }
+@@ -497,11 +498,14 @@
+       if ((p = strrchr(progname, '/')) != NULL)
+               progname = p+1;
+-      while ((c = getopt(argc, argv, "ade:E:fo:p:v")) != -1) {
++      while ((c = getopt(argc, argv, "ade:E:fo:p:vr")) != -1) {
+               switch (c) {
+               case 'a':
+                       all = 1;
+                       break;
++              case 'r':
++                      ro = 1;
++                      break;
+               case 'd':
+                       delete = 1;
+                       break;
+--- util-linux-2.13-pre6/mount/losetup.8.ronly 2006-11-01 14:49:14.000000000 +0100
++++ util-linux-2.13-pre6/mount/losetup.8       2006-11-01 15:06:21.000000000 +0100
+@@ -35,6 +35,7 @@
+ .IR offset ]
+ .RB [ \-p
+ .IR pfd ]
++.RB [ \-r ]
+ .in +8
+ .RB { \-f | \fIloop_device\fP }
+ .I file
+@@ -87,6 +88,8 @@
+ Read the passphrase from file descriptor with number
+ .I num
+ instead of from the terminal.
++.IP \fB\-r\fP
++Setup read-only loop device.
+ .SH RETURN VALUE
+ .B losetup
+ returns 0 on success, nonzero on failure. When
diff --git a/util-linux-lvm2dupes.patch b/util-linux-lvm2dupes.patch
new file mode 100644 (file)
index 0000000..07f4eb5
--- /dev/null
@@ -0,0 +1,29 @@
+- At boot time, fsck chokes on LVs listed by label in fstab
+
+--- util-linux-2.12p/mount/mount_by_label.c.lvm2dupes  2005-04-25 11:33:53.657880224 +0200
++++ util-linux-2.12p/mount/mount_by_label.c    2005-04-25 11:36:32.075797040 +0200
+@@ -195,6 +195,15 @@
+       return 1;
+ }
++/* We need to avoid listing /dev/dm-X devices, because they are added to the uuidcache separately by the
++   uuidcache_init_dm routine. Duplicate entries cause mount-by-label to fail.
++ */
++static int
++is_lvm2(char *ptname)
++{
++      return !strncmp(ptname, "dm-", 3);
++}
++
+ static void
+ uuidcache_init(void) {
+       char line[100];
+@@ -266,7 +275,7 @@
+               /* devfs has .../disc and .../part1 etc. */
+               for (s = ptname; *s; s++);
+-              if (isdigit(s[-1]) || is_xvm(ptname)) {
++              if ((isdigit(s[-1]) || is_xvm(ptname)) && !is_lvm2(ptname)) {
+                       
+               /*
+                * Note: this is a heuristic only - there is no reason
diff --git a/util-linux-mkswap-mounted.patch b/util-linux-mkswap-mounted.patch
new file mode 100644 (file)
index 0000000..1053021
--- /dev/null
@@ -0,0 +1,64 @@
+- mkswap "works" without warning on a mounted device
+
+--- util-linux-2.13-pre6/disk-utils/mkswap.c.kzak      2006-10-12 11:33:50.000000000 +0200
++++ util-linux-2.13-pre6/disk-utils/mkswap.c   2006-10-12 11:36:08.000000000 +0200
+@@ -36,6 +36,7 @@
+ #include <string.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
++#include <mntent.h>
+ #include <sys/ioctl.h>                /* for _IO */
+ #include <sys/utsname.h>
+ #include <sys/stat.h>
+@@ -485,6 +486,29 @@
+       return (c >= '1' && c <= '9');
+ }
++
++/*
++ * Check to make certain that our new filesystem won't be created on
++ * an already mounted partition.  Code adapted from mke2fs, Copyright
++ * (C) 1994 Theodore Ts'o.  Also licensed under GPL.
++ * (C) 2006 Karel Zak -- port to mkswap
++ */
++static int
++check_mount(void) {
++      FILE * f;
++      struct mntent * mnt;
++
++      if ((f = setmntent (MOUNTED, "r")) == NULL)
++              return 0;
++      while ((mnt = getmntent (f)) != NULL)
++              if (strcmp (device_name, mnt->mnt_fsname) == 0)
++                      break;
++      endmntent (f);
++      if (!mnt)
++              return 0;
++      return 1;
++}
++
+ int
+ main(int argc, char ** argv) {
+       struct stat statbuf;
+@@ -648,8 +672,19 @@
+       /* Want a block device. Probably not /dev/hda or /dev/hdb. */
+       if (!S_ISBLK(statbuf.st_mode))
+               check=0;
+-      else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
+-              die(_("Will not try to make swapdevice on '%s'"));
++      else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340) {
++              fprintf(stderr,
++                      _("%s: error: "
++                        "will not try to make swapdevice on '%s'\n"),
++                      program_name, device_name);
++              exit(1);
++      } else if (check_mount()) {
++              fprintf(stderr,
++                      _("%s: error: "
++                        "%s is mounted; will not make swapspace.\n"), 
++                      program_name, device_name);
++              exit(1);
++      }
+ #ifdef __sparc__
+       if (!force && version == 0) {
diff --git a/util-linux-mkswap-selinux.patch b/util-linux-mkswap-selinux.patch
new file mode 100644 (file)
index 0000000..004c69d
--- /dev/null
@@ -0,0 +1,83 @@
+- mkswap should automatically add selinux label to swapfile
+
+--- util-linux-2.13-pre6/disk-utils/mkswap.c.selinux   2005-08-14 17:34:49.000000000 +0200
++++ util-linux-2.13-pre6/disk-utils/mkswap.c   2006-03-08 16:35:08.000000000 +0100
+@@ -39,6 +39,12 @@
+ #include <sys/ioctl.h>                /* for _IO */
+ #include <sys/utsname.h>
+ #include <sys/stat.h>
++#include <errno.h>
++#ifdef HAVE_LIBSELINUX
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#endif
++
+ #include "swapheader.h"
+ #include "xstrncpy.h"
+ #include "nls.h"
+@@ -76,6 +82,8 @@
+ #define MAKE_VERSION(p,q,r)   (65536*(p) + 256*(q) + (r))
++#define SELINUX_SWAPFILE_TYPE "swapfile_t"
++
+ static int
+ linux_version_code(void) {
+       struct utsname my_utsname;
+@@ -718,5 +726,39 @@
+       if (fsync(DEV))
+                die(_("fsync failed"));
+ #endif
++
++#ifdef HAVE_LIBSELINUX
++      if (S_ISREG(statbuf.st_mode) && is_selinux_enabled()) {
++              security_context_t context_string;
++              security_context_t oldcontext;
++              context_t newcontext;
++
++              if ((fgetfilecon(DEV, &oldcontext) < 0) && 
++                  (errno != ENODATA)) {
++                      fprintf(stderr, _("%s: %s: unable to obtain selinux file label: %s\n"),
++                                      program_name, device_name, 
++                                      strerror(errno));
++                      exit(1);
++              }
++              if (!(newcontext = context_new(oldcontext)))
++                      die(_("unable to create new selinux context"));
++              if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
++                      die(_("couldn't compute selinux context"));
++              
++              context_string = context_str(newcontext);
++              
++              if (strcmp(context_string, oldcontext)!=0) {
++                      if (fsetfilecon(DEV, context_string)) {
++                              fprintf(stderr, _("%s: unable to relabel %s to %s: %s\n"),
++                                              program_name, device_name, 
++                                              context_string,
++                                              strerror(errno));
++                              exit(1);
++                      }
++              }
++              context_free(newcontext);
++              freecon(oldcontext);
++      }
++#endif
+       return 0;
+ }
+--- util-linux-2.13-pre6/disk-utils/Makefile.am.selinux        2005-09-10 19:46:10.000000000 +0200
++++ util-linux-2.13-pre6/disk-utils/Makefile.am        2006-03-08 16:27:03.000000000 +0100
+@@ -30,6 +30,13 @@
+ mkfs_cramfs_LDADD = -lz $(top_srcdir)/lib/libmd5.a
+ endif
++mkswap_LDADD =
++
+ if HAVE_UUID
+-mkswap_LDADD = -luuid
++mkswap_LDADD += -luuid
++endif
++
++if HAVE_SELINUX
++mkswap_LDADD += -lselinux
+ endif
++
diff --git a/util-linux-more-CLOEXEC.patch b/util-linux-more-CLOEXEC.patch
new file mode 100644 (file)
index 0000000..fe69e7a
--- /dev/null
@@ -0,0 +1,19 @@
+
+When you view a file with the more command and run a shell, the file descriptor
+for reading the file is leaked to that process.
+
+To test, more any file. Then do !/bin/sh. At the prompt do "ls -l /proc/$$/fd"
+and you'll see the leaked fd.
+
+From: Steve Grubb <sgrubb@redhat.com>
+
+--- util-linux-2.13-pre7/text-utils/more.c.cloexec     2006-12-14 14:05:31.000000000 +0100
++++ util-linux-2.13-pre7/text-utils/more.c     2006-12-14 14:04:57.000000000 +0100
+@@ -478,6 +478,7 @@
+       }
+       if (magic(f, fs))
+               return((FILE *)NULL);
++      fcntl(fileno(f), F_SETFD, FD_CLOEXEC );
+       c = Getc(f);
+       *clearfirst = (c == '\f');
+       Ungetc (c, f);
diff --git a/util-linux-mount-context.patch b/util-linux-mount-context.patch
new file mode 100644 (file)
index 0000000..31abd3d
--- /dev/null
@@ -0,0 +1,222 @@
+- mount does not translate SELIinux context options though libselinux
+- Need man page entry for -o context= mount option
+- Can't mount with additional contexts
+
+--- util-linux-2.13-pre6/mount/Makefile.am.context     2005-09-12 22:41:11.000000000 +0200
++++ util-linux-2.13-pre6/mount/Makefile.am     2006-11-01 11:31:46.000000000 +0100
+@@ -37,6 +37,9 @@
+ man_MANS += pivot_root.8
+ endif
++if HAVE_SELINUX
++mount_LDADD += -lselinux
++endif
+ swapon.c: swapargs.h
+--- util-linux-2.13-pre6/mount/mount.c.context 2006-11-01 11:31:46.000000000 +0100
++++ util-linux-2.13-pre6/mount/mount.c 2006-11-01 11:36:17.000000000 +0100
+@@ -21,6 +21,11 @@
+ #include <sys/wait.h>
+ #include <sys/mount.h>
++#ifdef HAVE_LIBSELINUX
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#endif
++
+ #include "mount_blkid.h"
+ #include "mount_constants.h"
+ #include "sundries.h"
+@@ -255,13 +260,79 @@
+               free((void *) s);
+ }
++#ifdef HAVE_LIBSELINUX
++/* strip quotes from a "string"
++ * Warning: This function modify the "str" argument.
++ */
++static char *
++strip_quotes(char *str)
++{
++      char *end = NULL;
++
++      if (*str != '"') 
++              return str;
++      
++      end = strrchr(str, '"');
++      if (end == NULL || end == str) 
++              die (EX_USAGE, _("mount: improperly quoted option string '%s'"), str);
++
++      *end = '\0';
++      return str+1;
++}
++
++/* translates SELinux context from human to raw format and 
++ * appends it to the mount extra options.
++ *
++ * returns -1 on error and 0 on success 
++ */
++static int
++append_context(const char *optname, char *optdata, char *extra_opts, int *len)
++{
++      security_context_t raw = NULL;
++      char *data = NULL;
++      char *buf = NULL;
++      int bufsz;
++      
++      if (!is_selinux_enabled())
++              /* ignore the option if we running without selinux */
++              return 0;
++
++      if (optdata==NULL || *optdata=='\0' || optname==NULL)
++              return -1;
++      
++      /* TODO: use strip_quotes() for all mount options? */
++      data = *optdata =='"' ? strip_quotes(optdata) : optdata;
++      
++      if (selinux_trans_to_raw_context(
++                      (security_context_t) data, &raw)==-1 ||
++                      raw==NULL) 
++              return -1;
++      
++      if (verbose)
++              printf(_("mount: translated %s '%s' to '%s'\n"), 
++                              optname, data, (char *) raw);
++        
++      bufsz = strlen(optname) + strlen(raw) + 4;      /* 4 is \0, '=' and 2x '"' */ 
++      buf = xmalloc(bufsz);
++
++      snprintf(buf, bufsz, "%s=\"%s\"", optname, (char *) raw);
++      freecon(raw);
++      
++      if ((*len -= bufsz-1) > 0)
++              strcat(extra_opts, buf);
++      
++      my_free(buf);
++      return 0;
++}
++#endif
++
+ /*
+  * Look for OPT in opt_map table and return mask value.
+  * If OPT isn't found, tack it onto extra_opts (which is non-NULL).
+  * For the options uid= and gid= replace user or group name by its value.
+  */
+ static inline void
+-parse_opt(const char *opt, int *mask, char *extra_opts, int len) {
++parse_opt(char *opt, int *mask, char *extra_opts, int len) {
+       const struct opt_map *om;
+       for (om = opt_map; om->opt != NULL; om++)
+@@ -313,7 +384,20 @@
+                       return;
+               }
+       }
+-
++#ifdef HAVE_LIBSELINUX
++      if (strncmp(opt, "context=", 8)==0 && *(opt+8)) {
++              if (append_context("context", opt+8, extra_opts, &len)==0)
++                      return;
++      }
++      if (strncmp(opt, "fscontext=", 10)==0 && *(opt+10)) {
++              if (append_context("fscontext", opt+10, extra_opts, &len)==0)
++                      return;
++      }
++      if (strncmp(opt, "defcontext=", 11)==0 && *(opt+11)) {
++              if (append_context("defcontext", opt+11, extra_opts, &len)==0)
++                      return;
++      }
++#endif
+       if ((len -= strlen(opt)) > 0)
+               strcat(extra_opts, opt);
+ }
+@@ -329,16 +413,29 @@
+       if (options != NULL) {
+               char *opts = xstrdup(options);
+-              char *opt;
+-              int len = strlen(opts) + 20;
++              int len = strlen(opts) + 256;
++              int open_quote = 0;
++              char *opt, *p;
+               *extra_opts = xmalloc(len); 
+               **extra_opts = '\0';
+-              for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ","))
+-                      if (!parse_string_opt(opt))
+-                              parse_opt(opt, flags, *extra_opts, len);
+-
++              for (p=opts, opt=NULL; p && *p; p++) {
++                      if (!opt)
++                              opt = p;                /* begin of the option item */
++                      if (*p == '"') 
++                              open_quote ^= 1;        /* reverse the status */
++                      if (open_quote)
++                              continue;               /* still in quoted block */
++                      if (*p == ',')
++                              *p = '\0';              /* terminate the option item */
++                      /* end of option item or last item */
++                      if (*p == '\0' || *(p+1) == '\0') {
++                              if (!parse_string_opt(opt))
++                                      parse_opt(opt, flags, *extra_opts, len);
++                              opt = NULL;
++                      }
++              } 
+               free(opts);
+       }
+--- util-linux-2.13-pre6/mount/mount.8.context 2006-11-01 11:31:46.000000000 +0100
++++ util-linux-2.13-pre6/mount/mount.8 2006-11-01 11:31:46.000000000 +0100
+@@ -660,6 +660,50 @@
+ .BR noexec ", " nosuid ", and " nodev
+ (unless overridden by subsequent options, as in the option line
+ .BR users,exec,dev,suid ).
++.TP
++\fBcontext=\fP\fIcontext\fP, \fBfscontext=\fP\fIcontext\fP and \fBdefcontext=\fP\fIcontext\fP
++The 
++.BR context= 
++option is useful when mounting filesystems that do not support
++extended attributes, such as a floppy or hard disk formatted with VFAT, or
++systems that are not normally running under SELinux, such as an ext3 formatted
++disk from a non-SELinux workstation. You can also use
++.BR context= 
++on filesystems you do not trust, such as a floppy. It also helps in compatibility with
++xattr-supporting filesystems on earlier 2.4.<x> kernel versions. Even where
++xattrs are supported, you can save time not having to label every file by
++assigning the entire disk one security context.
++
++A commonly used option for removable media is 
++.BR context=system_u:object_r:removable_t .
++
++Two other options are 
++.BR fscontext= 
++and 
++.BR defcontext= ,
++both of which are mutually exclusive of the context option. This means you
++can use fscontext and defcontext with each other, but neither can be used with
++context.
++
++The 
++.BR fscontext= 
++option works for all filesystems, regardless of their xattr
++support. The fscontext option sets the overarching filesystem label to a
++specific security context. This filesystem label is separate from the
++individual labels on the files. It represents the entire filesystem for
++certain kinds of permission checks, such as during mount or file creation.
++Individual file labels are still obtained from the xattrs on the files
++themselves. The context option actually sets the aggregate context that
++fscontext provides, in addition to supplying the same label for individual
++files.
++
++You can set the default security context for unlabeled files using 
++.BR defcontext=
++option. This overrides the value set for unlabeled files in the policy and requires a
++file system that supports xattr labeling. 
++
++For more details see 
++.BR selinux (8)
+ .RE
+ .TP
+ .B \-\-bind
diff --git a/util-linux-mount-man-bugs.patch b/util-linux-mount-man-bugs.patch
new file mode 100644 (file)
index 0000000..1acbfa9
--- /dev/null
@@ -0,0 +1,29 @@
+- missing info about /etc/mtab and /proc/mounts mismatch
+- missing info about possible ioctl() and fcntl() problems on NFS filesystem
+
+--- util-linux-2.13-pre7/mount/mount.8.bugs    2006-03-30 21:36:56.000000000 +0200
++++ util-linux-2.13-pre7/mount/mount.8 2006-03-30 21:37:35.000000000 +0200
+@@ -2047,6 +2047,23 @@
+ .IR /proc/partitions .
+ In particular, it may well fail if the kernel was compiled with devfs
+ but devfs is not mounted.
++.PP
++It is possible that files 
++.IR /etc/mtab
++and 
++.IR /proc/mounts
++don't match. The first file is based only on the mount command options, but the
++content of the second file also depends on the kernel and others settings (e.g.
++remote NFS server. In particular case the mount command may reports unreliable
++information about a NFS mount point and the /proc/mounts file usually contains
++more reliable information.)
++.PP
++Checking files on NFS filesystem referenced by file descriptors (i.e. the 
++.BR fcntl 
++and 
++.BR ioctl
++families of functions) may lead to inconsistent result due to the lack of
++consistency check in kernel even if noac is used.
+ .SH HISTORY
+ A
+ .B mount
diff --git a/util-linux-mount-man-cifs.patch b/util-linux-mount-man-cifs.patch
new file mode 100644 (file)
index 0000000..df673ef
--- /dev/null
@@ -0,0 +1,19 @@
+--- util-linux-2.12a/mount/mount.8.cifs        2005-11-23 16:34:34.000000000 +0100
++++ util-linux-2.12a/mount/mount.8     2005-11-23 16:38:37.000000000 +0100
+@@ -720,6 +720,16 @@
+ (However, quota utilities may react to such strings in
+ .IR /etc/fstab .)
++.SH "Mount options for cifs"
++Just like
++.IR nfs " or " smbfs
++implementation expects a binary argument 
++to the mount system call. This argument is constructed by
++.BR mount.cifs (8)
++and the current version of
++.B mount
++(2.12) does not know anything about cifs.
++
+ .SH "Mount options for coherent"
+ None.
diff --git a/util-linux-mount-man-nfs.patch b/util-linux-mount-man-nfs.patch
new file mode 100644 (file)
index 0000000..961a998
--- /dev/null
@@ -0,0 +1,28 @@
+- Documentation for 'rsize' and 'wsize' NFS mount options is misleading
+
+--- util-linux-2.12p/mount/mount.8.nfsdoc      2005-05-10 11:46:25.119592000 -0400
++++ util-linux-2.12p/mount/mount.8     2005-10-07 09:46:13.374277000 -0400
+@@ -1339,12 +1339,17 @@ For details, see
+ Especially useful options include
+ .TP
+-.B rsize=8192,wsize=8192
+-This will make your nfs connection faster than with the default
+-buffer size of 4096. (NFSv2 does not work with larger values of
+-.B rsize
+-and
+-.BR wsize .)
++.B rsize=32768,wsize=32768
++This causes the NFS client to try to negotiate a buffer size
++up to the size specified.
++A large buffer size does improve performance, but both the 
++server and client have to support it.
++In the case where one of these does not support the size specified, 
++the size negotiated will be the largest that both support.
++.TP
++.B intr
++This will allow NFS operations (on hard mounts) to be 
++interrupted while waiting for a response from the server. 
+ .TP
+ .B hard
+ The program accessing a file on a NFS mounted file system will hang
diff --git a/util-linux-mount-man-nfs4.patch b/util-linux-mount-man-nfs4.patch
new file mode 100644 (file)
index 0000000..0e1afd9
--- /dev/null
@@ -0,0 +1,114 @@
+--- util-linux-2.13-pre7/mount/mount.8.man-nfs4        2006-03-06 00:04:37.000000000 +0100
++++ util-linux-2.13-pre7/mount/mount.8 2006-12-14 00:30:33.000000000 +0100
+@@ -385,6 +385,7 @@
+ .IR msdos ,
+ .IR ncpfs ,
+ .IR nfs ,
++.IR nfs4 ,
+ .IR ntfs ,
+ .IR proc ,
+ .IR qnx4 ,
+@@ -422,7 +423,7 @@
+ program has to do is issue a simple
+ .IR mount (2)
+ system call, and no detailed knowledge of the filesystem type is required.
+-For a few types however (like nfs, cifs, smbfs, ncpfs) ad hoc code is
++For a few types however (like nfs, nfs4, cifs, smbfs, ncpfs) ad hoc code is
+ necessary. The nfs ad hoc code is built in, but cifs, smbfs, and ncpfs
+ have a separate mount program. In order to make it possible to
+ treat all types in a uniform way, mount will execute the program
+@@ -450,9 +451,10 @@
+ All of the filesystem types listed there will be tried,
+ except for those that are labeled "nodev" (e.g.,
+ .IR devpts ,
+-.I proc
++.IR proc ,
++.IR nfs ,
+ and
+-.IR nfs ).
++.IR nfs4 ).
+ If
+ .I /etc/filesystems
+ ends in a line with a single * only, mount will read
+@@ -1368,6 +1370,81 @@
+ .B nolock
+ Do not use locking. Do not start lockd.
++.SH "Mount options for nfs4"
++Instead of a textual option string, parsed by the kernel, the
++.I nfs4
++file system expects a binary argument of type
++.IR "struct nfs4_mount_data" .
++The program
++.B mount
++itself parses the following options of the form `tag=value',
++and puts them in the structure mentioned:
++.BI rsize= n,
++.BI wsize= n,
++.BI timeo= n,
++.BI retrans= n,
++.BI acregmin= n,
++.BI acregmax= n,
++.BI acdirmin= n,
++.BI acdirmax= n,
++.BI actimeo= n,
++.BI retry= n,
++.BI port= n,
++.BI proto= n,
++.BI clientaddr= n,
++.BI sec= n.
++The option
++.BI addr= n
++is accepted but ignored.
++Also the following Boolean options, possibly preceded by
++.B no
++are recognized:
++.BR bg ,
++.BR fg ,
++.BR soft ,
++.BR hard ,
++.BR intr ,
++.BR cto ,
++.BR ac ,
++For details, see
++.BR nfs (5).
++
++Especially useful options include
++.TP
++.B rsize=32768,wsize=32768
++This causes the NFS4 client to try to negotiate a buffer size
++up to the size specified.
++A large buffer size does improve performance, but both the 
++server and client have to support it.
++In the case where one of these does not support the size specified, 
++the size negotiated will be the largest that both support.
++.TP
++.B intr
++This will allow NFS4 operations (on hard mounts) to be 
++interrupted while waiting for a response from the server. 
++.TP
++.B hard
++The program accessing a file on a NFS mounted file system will hang
++when the server crashes. The process cannot be interrupted or
++killed unless you also specify
++.BR intr .
++When the NFS server is back online the program will continue undisturbed
++from where it was. This is probably what you want.
++.TP
++.B soft
++This option allows the kernel to time out if the NFS server is not
++responding for some time. The time can be
++specified with
++.BR timeo=time .
++This timeout value is expressed in tenths of a second.
++The
++.BR soft
++option might be useful if your NFS server sometimes doesn't respond
++or will be rebooted while some process tries to get a file from the server.
++Avoid using this option with
++.BR proto=udp
++or with a short timeout.
++
+ .SH "Mount options for ntfs"
+ .TP
+ .BI iocharset= name
diff --git a/util-linux-mount-nonfs.patch b/util-linux-mount-nonfs.patch
new file mode 100644 (file)
index 0000000..37eb008
--- /dev/null
@@ -0,0 +1,196 @@
+--- util-linux-2.13-pre6/mount/Makefile.am.nonfs       2006-09-20 12:45:50.000000000 +0200
++++ util-linux-2.13-pre6/mount/Makefile.am     2006-09-20 12:46:51.000000000 +0200
+@@ -1,15 +1,12 @@
+ include $(top_srcdir)/config/include-Makefile.am
+-AM_CPPFLAGS += -DHAVE_NFS
+-
+ bin_PROGRAMS = mount umount
+ sbin_PROGRAMS = losetup swapon
+-man_MANS = fstab.5 nfs.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
++man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
+ mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mntent.c \
+       get_label_uuid.c mount_by_label.c mount_blkid.c mount_guess_fstype.c \
+       getusername.c cryptsetup.c \
+-      nfsmount.c nfsmount_xdr.c nfsmount_clnt.c \
+       lomount.c
+ mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a
+--- util-linux-2.13-pre6/mount/sundries.c.nonfs        2006-09-20 12:53:09.000000000 +0200
++++ util-linux-2.13-pre6/mount/sundries.c      2006-09-20 12:53:13.000000000 +0200
+@@ -15,7 +15,6 @@
+ #include "fstab.h"
+ #include "sundries.h"
+ #include "realpath.h"
+-#include "nfsmount.h"
+ #include "nls.h"
+ char *
+--- util-linux-2.13-pre6/mount/umount.c.nonfs  2006-09-20 12:51:11.000000000 +0200
++++ util-linux-2.13-pre6/mount/umount.c        2006-09-20 12:52:26.000000000 +0200
+@@ -20,15 +20,6 @@
+ #include "env.h"
+ #include "nls.h"
+-#include <sys/socket.h>
+-#include <sys/time.h>
+-#include <netdb.h>
+-#include <rpc/rpc.h>
+-#include <rpc/pmap_clnt.h>
+-#include <rpc/pmap_prot.h>
+-#include "nfsmount.h"
+-#include <arpa/inet.h>
+-
+ #if defined(MNT_FORCE) && !defined(__sparc__) && !defined(__arm__)
+ /* Interesting ... it seems libc knows about MNT_FORCE and presumably
+    about umount2 as well -- need not do anything */
+@@ -144,98 +135,6 @@
+       return 0;
+ }
+-static int xdr_dir(XDR *xdrsp, char *dirp)
+-{
+-      return (xdr_string(xdrsp, &dirp, MNTPATHLEN));
+-}
+-
+-static int
+-nfs_umount_rpc_call(const char *spec, const char *opts)
+-{
+-      register CLIENT *clp;
+-      struct sockaddr_in saddr;
+-      struct timeval pertry, try;
+-      enum clnt_stat clnt_stat;
+-      int port = 0;
+-      int so = RPC_ANYSOCK;
+-      struct hostent *hostp;
+-      char *hostname;
+-      char *dirname;
+-      char *p;
+-
+-      if (spec == NULL || (p = strchr(spec,':')) == NULL)
+-              return 0;
+-      hostname = xstrndup(spec, p-spec);
+-      dirname = xstrdup(p+1);
+-#ifdef DEBUG
+-      printf(_("host: %s, directory: %s\n"), hostname, dirname);
+-#endif
+-
+-      if (opts && (p = strstr(opts, "addr="))) {
+-         char *q;
+-
+-         free(hostname);
+-         p += 5;
+-         q = p;
+-         while (*q && *q != ',') q++;
+-         hostname = xstrndup(p,q-p);
+-      }
+-
+-      if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
+-         port = atoi(p+10);
+-
+-      if (hostname[0] >= '0' && hostname[0] <= '9')
+-         saddr.sin_addr.s_addr = inet_addr(hostname);
+-      else {
+-         if ((hostp = gethostbyname(hostname)) == NULL) {
+-              fprintf(stderr, _("umount: can't get address for %s\n"),
+-                      hostname);
+-              return 1;
+-         }
+-         if (hostp->h_length > sizeof(struct in_addr)) {
+-              fprintf(stderr, _("umount: got bad hostp->h_length\n"));
+-              hostp->h_length = sizeof(struct in_addr);
+-         }
+-         memcpy(&saddr.sin_addr, hostp->h_addr, hostp->h_length);
+-      }
+-
+-      saddr.sin_family = AF_INET;
+-      saddr.sin_port = htons(port);
+-      pertry.tv_sec = 3;
+-      pertry.tv_usec = 0;
+-      if (opts && (p = strstr(opts, "tcp"))) {
+-         /* possibly: make sure option is not "notcp"
+-            possibly: try udp if tcp fails */
+-         if ((clp = clnttcp_create(&saddr, MOUNTPROG, MOUNTVERS,
+-                                   &so, 0, 0)) == NULL) {
+-              clnt_pcreateerror("Cannot MOUNTPROG RPC (tcp)");
+-              return 1;
+-         }
+-      } else {
+-           if ((clp = clntudp_create(&saddr, MOUNTPROG, MOUNTVERS,
+-                                   pertry, &so)) == NULL) {
+-              clnt_pcreateerror("Cannot MOUNTPROG RPC");
+-              return 1;
+-         }
+-      }
+-      clp->cl_auth = authunix_create_default();
+-      try.tv_sec = 20;
+-      try.tv_usec = 0;
+-      clnt_stat = clnt_call(clp, MOUNTPROC_UMNT,
+-                          (xdrproc_t) xdr_dir, dirname,
+-                          (xdrproc_t) xdr_void, (caddr_t) 0,
+-                          try);
+-
+-      if (clnt_stat != RPC_SUCCESS) {
+-         clnt_perror(clp, "Bad UMNT RPC");
+-         return 1;
+-      }
+-      auth_destroy(clp->cl_auth);
+-      clnt_destroy(clp);
+-
+-      return 0;
+-}
+-
+ /* complain about a failed umount */
+ static void complain(int err, const char *dev) {
+   switch (err) {
+@@ -289,11 +188,6 @@
+       if (check_special_umountprog(spec, node, type, &status))
+               return status;
+-      /* Ignore any RPC errors, so that you can umount the filesystem
+-         if the server is down.  */
+-      if (strcasecmp(type, "nfs") == 0)
+-              nfs_umount_rpc_call(spec, opts);
+- 
+       umnt_err = umnt_err2 = 0;
+       if (lazy) {
+               res = umount2 (node, MNT_DETACH);
+--- util-linux-2.13-pre6/mount/mount.c.nonfs   2006-09-20 12:48:48.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.c 2006-09-20 12:48:33.000000000 +0200
+@@ -966,19 +966,6 @@
+       goto out;
+   }
+-  /*
+-   * Also nfs requires a separate program, but it is built in.
+-   */
+-  if (!fake && types && streq (types, "nfs")) {
+-retry_nfs:
+-    mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
+-                      &nfs_mount_version, bg);
+-    if (mnt_err) {
+-      res = mnt_err;
+-      goto out;
+-    }
+-  }
+-
+   block_signals (SIG_BLOCK);
+   if (!fake) {
+@@ -1018,15 +1005,6 @@
+   block_signals (SIG_UNBLOCK);
+-  if (mnt_err && types && streq (types, "nfs")) {
+-      if (nfs_mount_version == 4 && mnt_err != EBUSY && mnt_err != ENOENT) {
+-        if (verbose)
+-          printf(_("mount: failed with nfs mount version 4, trying 3..\n"));
+-        nfs_mount_version = 3;
+-        goto retry_nfs;
+-      }
+-  }
+-
+   /* Mount failed, complain, but don't die.  */
+   if (types == 0) {
diff --git a/util-linux-mount-sloppy.patch b/util-linux-mount-sloppy.patch
new file mode 100644 (file)
index 0000000..4dc338f
--- /dev/null
@@ -0,0 +1,22 @@
+- mount not allowing sloppy option
+
+--- util-linux-2.13-pre6/mount/mount.c.sloppy  2006-09-15 08:39:53.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.c 2006-09-15 08:43:24.000000000 +0200
+@@ -554,7 +554,7 @@
+        if (stat(mountprog, &statbuf) == 0) {
+           res = fork();
+           if (res == 0) {
+-               const char *oo, *mountargs[10];
++               const char *oo, *mountargs[12];
+                int i = 0;
+                setuid(getuid());
+@@ -563,6 +563,8 @@
+                mountargs[i++] = mountprog;
+                mountargs[i++] = spec;
+                mountargs[i++] = node;
++               if (sloppy && (strcmp(type, "nfs")==0 || strcmp(type, "nfs4")==0))
++                    mountargs[i++] = "-s";
+                if (nomtab)
+                     mountargs[i++] = "-n";
+                if (verbose)
diff --git a/util-linux-mount-subtree.patch b/util-linux-mount-subtree.patch
new file mode 100644 (file)
index 0000000..77fe475
--- /dev/null
@@ -0,0 +1,199 @@
+--- util-linux-2.13-pre6/mount/mount.8.subtree 2006-06-12 09:18:26.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.8 2006-06-12 09:19:43.000000000 +0200
+@@ -131,6 +131,41 @@
+ .B "mount --move olddir newdir"
+ .RE
++Since Linux 2.6.15 it is possible to mark a mount and its submounts as shared,
++private, slave or unbindable. A shared mount provides ability to create mirrors
++of that mount such that mounts and umounts within any of the mirrors propagate
++to the other mirror. A slave mount receives propagation from its master, but
++any not vice-versa.  A private mount carries no propagation abilities.  A
++unbindable mount is a private mount which cannot cloned through a bind
++operation. Detailed semantics is documented in Documentation/sharedsubtree.txt
++file in the kernel source tree.
++.RS
++.br
++.B "mount --make-shared mountpoint"
++.br
++.B "mount --make-slave mountpoint"
++.br
++.B "mount --make-private mountpoint"
++.br
++.B "mount --make-unbindable mountpoint"
++.br
++.RE
++
++The following commands allows one to recursively change the type of all the
++mounts under a given mountpoint.
++.RS
++.br
++.B "mount --make-rshared mountpoint"
++.br
++.B "mount --make-rslave mountpoint"
++.br
++.B "mount --make-rprivate mountpoint"
++.br
++.B
++"mount --make-runbindable mountpoint"
++.br
++.RE
++
+ The
+ .I proc
+ file system is not associated with a special device, and when
+--- util-linux-2.13-pre6/mount/mount_constants.h.subtree       2002-11-01 01:24:36.000000000 +0100
++++ util-linux-2.13-pre6/mount/mount_constants.h       2006-06-12 09:19:43.000000000 +0200
+@@ -57,6 +57,18 @@
+ #ifndef MS_VERBOSE
+ #define MS_VERBOSE    0x8000  /* 32768 */
+ #endif
++#ifndef MS_UNBINDABLE
++#define MS_UNBINDABLE (1<<17) /* 131072 unbindable*/
++#endif
++#ifndef MS_PRIVATE
++#define MS_PRIVATE    (1<<18) /* 262144 Private*/
++#endif
++#ifndef MS_SLAVE
++#define MS_SLAVE      (1<<19) /* 524288 Slave*/
++#endif
++#ifndef MS_SHARED
++#define MS_SHARED     (1<<20) /* 1048576 Shared*/
++#endif
+ /*
+  * Magic mount flag number. Had to be or-ed to the flag values.
+  */
+--- util-linux-2.13-pre6/mount/mount.c.subtree 2006-06-12 09:18:26.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.c 2006-06-12 09:19:43.000000000 +0200
+@@ -74,7 +74,9 @@
+ /* Add volumelabel in a listing of mounted devices (-l). */
+ static int list_with_volumelabel = 0;
+-/* Nonzero for mount {--bind|--replace|--before|--after|--over|--move} */
++/* Nonzero for mount {--bind|--replace|--before|--after|--over|--move|
++ *                   make-shared|make-private|make-unbindable|make-slave}
++ */
+ static int mounttype = 0;
+ /* True if ruid != euid.  */
+@@ -103,16 +105,18 @@
+ #define MS_USER               0x20000000
+ #define MS_OWNER      0x10000000
+ #define MS_GROUP      0x08000000
+-#define       MS_CRYPT        0x00040000
+-#define MS_COMMENT    0x00020000
++#define       MS_CRYPT        0x04000000
++#define MS_COMMENT    0x02000000
+ #define MS_LOOP               0x00010000
+ /* Options that we keep the mount system call from seeing.  */
+ #define MS_NOSYS      (MS_NOAUTO|MS_USERS|MS_USER|MS_COMMENT|MS_LOOP)
+ /* Options that we keep from appearing in the options field in the mtab.  */
+ #define MS_NOMTAB     (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
++#define MS_PROPAGATION  (MS_SHARED|MS_SLAVE|MS_UNBINDABLE|MS_PRIVATE)
++
+ /* Options that we make ordinary users have by default.  */
+ #define MS_SECURE     (MS_NOEXEC|MS_NOSUID|MS_NODEV)
+
+@@ -346,6 +350,9 @@
+               *flags |= MS_RDONLY;
+       if (readwrite)
+               *flags &= ~MS_RDONLY;
++
++      if (mounttype & MS_PROPAGATION)
++              *flags &= ~MS_BIND;
+       *flags |= mounttype;
+ }
+@@ -916,13 +923,15 @@
+       opt_encryption = tmp;
+       }
+-      update_mtab_entry(loop ? loopfile : crypt ? realdev : spec,
++      if (!(mounttype & MS_PROPAGATION)) {
++            update_mtab_entry(loop ? loopfile : crypt ? realdev : spec,
+                       node,
+                       types ? types : "unknown",
+                       fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user),
+                       flags,
+                       freq,
+                       pass);
++      }
+       block_signals (SIG_UNBLOCK);
+       res = 0;
+@@ -1461,6 +1470,14 @@
+       { "move", 0, 0, 133 },
+       { "guess-fstype", 1, 0, 134 },
+       { "rbind", 0, 0, 135 },
++      { "make-shared", 0, 0, 136 },
++      { "make-slave", 0, 0, 137 },
++      { "make-private", 0, 0, 138 },
++      { "make-unbindable", 0, 0, 139 },
++      { "make-rshared", 0, 0, 140 },
++      { "make-rslave", 0, 0, 141 },
++      { "make-rprivate", 0, 0, 142 },
++      { "make-runbindable", 0, 0, 143 },
+       { "internal-only", 0, 0, 'i' },
+       { NULL, 0, 0, 0 }
+ };
+@@ -1487,6 +1504,17 @@
+         "       mount --bind olddir newdir\n"
+         "or move a subtree:\n"
+         "       mount --move olddir newdir\n"
++        "One can change the type of mount containing the directory dir:\n"
++        "       mount --make-shared dir\n"
++        "       mount --make-slave dir\n"
++        "       mount --make-private dir\n"
++        "       mount --make-unbindable dir\n"
++        "One can change the type of all the mounts in a mount subtree\n"
++        "containing the directory dir:\n"
++        "       mount --make-rshared dir\n"
++        "       mount --make-rslave dir\n"
++        "       mount --make-rprivate dir\n"
++        "       mount --make-runbindable dir\n"
+         "A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
+         "or by label, using  -L label  or by uuid, using  -U uuid .\n"
+         "Other options: [-nfFrsvw] [-o options] [-p passwdfd].\n"
+@@ -1638,6 +1666,39 @@
+               case 135:
+                       mounttype = (MS_BIND | MS_REC);
+                       break;
++
++              case 136:
++                      mounttype = MS_SHARED;
++                      break;
++
++              case 137:
++                      mounttype = MS_SLAVE;
++                      break;
++
++              case 138:
++                      mounttype = MS_PRIVATE;
++                      break;
++
++              case 139:
++                      mounttype = MS_UNBINDABLE;
++                      break;
++
++              case 140:
++                      mounttype = (MS_SHARED | MS_REC);
++                      break;
++
++              case 141:
++                      mounttype = (MS_SLAVE | MS_REC);
++                      break;
++
++              case 142:
++                      mounttype = (MS_PRIVATE | MS_REC);
++                      break;
++
++              case 143:
++                      mounttype = (MS_UNBINDABLE | MS_REC);
++                      break;
++
+               case '?':
+               default:
+                       usage (stderr, EX_USAGE);
diff --git a/util-linux-mount-twiceloop.patch b/util-linux-mount-twiceloop.patch
new file mode 100644 (file)
index 0000000..a750828
--- /dev/null
@@ -0,0 +1,75 @@
+- mount allows loopback devices to be mounted
+  more than once to the same mount point
+
+--- util-linux-2.13-pre6/mount/fstab.h.twiceloop       2006-09-15 08:50:46.000000000 +0200
++++ util-linux-2.13-pre6/mount/fstab.h 2006-09-15 08:51:10.000000000 +0200
+@@ -2,6 +2,7 @@
+ int mtab_is_writable(void);
+ int mtab_does_not_exist(void);
+ int is_mounted_once(const char *name);
++int is_mounted_same_loopfile(const char *loopfile, const char *dir);
+ struct mntentchn {
+       struct mntentchn *nxt, *prev;
+--- util-linux-2.13-pre6/mount/mount.c.twiceloop       2006-09-15 08:50:23.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.c 2006-09-15 08:50:24.000000000 +0200
+@@ -671,7 +671,7 @@
+ static int
+ loop_check(const char **spec, const char **type, int *flags,
+-         int *loop, const char **loopdev, const char **loopfile) {
++         int *loop, const char **loopdev, const char **loopfile, const char *dir) {
+   int looptype;
+   unsigned long long offset;
+@@ -709,6 +709,11 @@
+     } else {
+       int loopro = (*flags & MS_RDONLY);
++      if (is_mounted_same_loopfile(*loopfile, dir)) {
++      error(_("mount: %s already mounted on %s"), *loopfile, dir);
++      return EX_FAIL;
++      }
++      
+       if (!*loopdev || !**loopdev)
+       *loopdev = find_unused_loop_device();
+       if (!*loopdev)
+@@ -856,7 +861,7 @@
+        * stale assignments of files to loop devices. Nasty when used for
+        * encryption.
+        */
+-      res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
++      res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile, node);
+       if (res)
+         goto out;
+   }
+--- util-linux-2.13-pre6/mount/fstab.c.twiceloop       2006-09-15 08:50:23.000000000 +0200
++++ util-linux-2.13-pre6/mount/fstab.c 2006-09-15 08:50:24.000000000 +0200
+@@ -254,6 +254,27 @@
+       return (ct == 1);
+ }
++/*
++ * Given the loop file LOOPFILE, and the mount point DIR, check that
++ * same file is already mounted on same directory 
++ *
++ * Don't forget there's 
++ *   /path/loopfile /path/dir loop=/dev/loop0
++ * in mtab for loop devices.
++ */
++int
++is_mounted_same_loopfile(const char *loopfile, const char *dir) {
++      struct mntentchn *mc, *mc0;
++      int ct = 0;
++
++      mc0 = mtab_head();
++      for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
++              if (streq(mc->m.mnt_fsname, loopfile) && 
++                  streq(mc->m.mnt_dir, dir))
++                      ct++;
++      return (ct == 1);
++}
++
+ /* Given the name FILE, try to find the option "loop=FILE" in mtab.  */ 
+ struct mntentchn *
+ getmntoptfile (const char *file) {
diff --git a/util-linux-mount-uhelper.patch b/util-linux-mount-uhelper.patch
new file mode 100644 (file)
index 0000000..8c90289
--- /dev/null
@@ -0,0 +1,70 @@
+- util-linux should provide plugin infrastructure for HAL
+
+--- util-linux-2.13-pre6/mount/mount.c.uhelper 2006-09-15 13:23:23.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount.c 2006-09-15 13:23:23.000000000 +0200
+@@ -183,7 +183,7 @@
+ };
+ static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
+-      *opt_speed, *opt_comment;
++      *opt_speed, *opt_comment, *opt_uhelper;
+ static struct string_opt_map {
+   char *tag;
+@@ -196,6 +196,7 @@
+   { "encryption=", 0, &opt_encryption },
+   { "speed=", 0, &opt_speed },
+   { "comment=", 1, &opt_comment },
++  { "uhelper=", 0, &opt_uhelper },
+   { NULL, 0, NULL }
+ };
+--- util-linux-2.13-pre6/mount/umount.8.uhelper        2004-11-10 20:49:37.000000000 +0100
++++ util-linux-2.13-pre6/mount/umount.8        2006-09-15 14:02:25.000000000 +0200
+@@ -122,6 +122,19 @@
+ Any pending loop devices can be freed using `losetup -d', see
+ .BR losetup (8).
++.SH NOTES
++The syntax of external umount helpers is:
++
++.br
++.BI "/sbin/umount.<suffix> [\-nlfvr] " "dir " | " device "
++.br
++
++where the <suffix> is filesystem type or a value from "uhelper=" mtab option. 
++
++The uhelper (unprivileged umount request helper) is possible used when non-root
++user wants to umount a mountpoint which is not defined in the /etc/fstab file 
++(e.g devices mounted by HAL).
++
+ .SH FILES
+ .I /etc/mtab
+ table of mounted file systems
+--- util-linux-2.13-pre6/mount/umount.c.uhelper        2006-09-15 13:23:23.000000000 +0200
++++ util-linux-2.13-pre6/mount/umount.c        2006-09-15 13:23:23.000000000 +0200
+@@ -565,11 +565,24 @@
+       if (suid) {
+               char *mtab_user = NULL;
++              char *uhelper = NULL;
+               if (!mc)
+                       die(2,
+                           _("umount: %s is not mounted (according to mtab)"),
+                           file);
++              /*
++               * uhelper - unprivileged umount helper
++               * -- external umount (for example HAL mounts)
++               */
++              if (mc->m.mnt_opts) 
++                      uhelper = get_value(mc->m.mnt_opts, "uhelper=");
++              if (uhelper) {
++                      int status = 0; 
++                      if (check_special_umountprog(arg, arg, uhelper, &status))
++                              return status;
++              }
++
+               /* The 2.4 kernel will generally refuse to mount the same
+                  filesystem on the same mount point, but will accept NFS.
+                  So, unmounting must be possible. */
diff --git a/util-linux-mount-uuid.patch b/util-linux-mount-uuid.patch
new file mode 100644 (file)
index 0000000..43a4d7a
--- /dev/null
@@ -0,0 +1,60 @@
+
+ The UUID code in the mount command is broken -- en example UUID= in the fstab
+ file is reason for SIGSEG when non-root user tries umount any device.
+ -- 03/30/2006 Karel Zak <kzak@redhat.com> 
+
+--- util-linux-2.13-pre6/mount/mount_blkid.h.uuid      2006-03-29 15:34:24.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount_blkid.h   2006-03-29 15:34:57.000000000 +0200
+@@ -8,5 +8,6 @@
+ extern const char *mount_get_devname_by_uuid(const char *uuid);
+ extern const char *mount_get_devname_by_label(const char *label);
+ extern const char *mount_get_volume_label_by_spec(const char *spec);
++extern const char *mount_get_volume_uuid_by_spec(const char *spec);
+ extern const char *mount_get_devname(const char *spec);
+ extern const char *mount_get_devname_for_mounting(const char *spec);
+--- util-linux-2.13-pre6/mount/mount_blkid.c.uuid      2006-03-29 15:33:44.000000000 +0200
++++ util-linux-2.13-pre6/mount/mount_blkid.c   2006-03-29 15:34:14.000000000 +0200
+@@ -21,6 +21,11 @@
+ }
+ const char *
++mount_get_volume_uuid_by_spec(const char *spec) {
++      return blkid_get_tag_value(blkid, "UUID", spec);
++}
++
++const char *
+ mount_get_devname(const char *spec) {
+       return blkid_get_devname(blkid, spec, 0);
+ }
+--- util-linux-2.13-pre6/mount/fstab.c.uuid    2006-03-29 15:29:28.000000000 +0200
++++ util-linux-2.13-pre6/mount/fstab.c 2006-03-29 15:36:30.000000000 +0200
+@@ -301,23 +301,19 @@
+ static int
+ has_label(const char *device, const char *label) {
+       const char *devlabel;
+-      int ret;
+-      devlabel = mount_get_volume_label_by_spec(device);
+-      ret = !strcmp(label, devlabel);
+-      /* free(devlabel); */
+-      return ret;
++      if (!(devlabel = mount_get_volume_label_by_spec(device)))
++              return 0;
++      return !strcmp(label, devlabel);
+ }
+ static int
+ has_uuid(const char *device, const char *uuid){
+       const char *devuuid;
+-      int ret;
+-      devuuid = mount_get_devname_by_uuid(device);
+-      ret = !strcmp(uuid, devuuid);
+-      /* free(devuuid); */
+-      return ret;
++      if (!(devuuid = mount_get_volume_uuid_by_spec(device)))
++              return 0;
++      return !strcmp(uuid, devuuid);
+ }
+ /* Find the entry (SPEC,FILE) in fstab */
diff --git a/util-linux-mountbylabel-dm.patch b/util-linux-mountbylabel-dm.patch
new file mode 100644 (file)
index 0000000..fd8f567
--- /dev/null
@@ -0,0 +1,63 @@
+--- util-linux-2.12a/mount/mount_by_label.c.old        2004-08-11 22:25:06.000000000 +0100
++++ util-linux-2.12a/mount/mount_by_label.c    2004-08-11 22:25:21.000000000 +0100
+@@ -17,6 +17,8 @@
+  * - Added JFS v2 format support
+  * 2002-07-26 Luciano Chavez <lnx1138@us.ibm.com>
+  * - Added EVMS support
++ * 2004-08-11 Alasdair Kergon <agk@redhat.com>
++ * - Added LVM2/device-mapper support
+  */
+ #include <stdio.h>
+@@ -38,6 +40,7 @@
+ #define VG_DIR          "/proc/lvm/VGs"
+ #define EVMS_VOLUME_NAME_SIZE  127
+ #define PROC_EVMS_VOLUMES "/proc/evms/volumes"
++#define DEVICEMAPPERDIR "/dev/mapper"
+ static struct uuidCache_s {
+       struct uuidCache_s *next;
+@@ -101,6 +104,34 @@
+       closedir(vg_dir);
+ }
++/* LVM2/device-mapper support */
++static void
++uuidcache_init_dm(void) {
++      char lvm_device[PATH_MAX];
++      DIR *d;
++      struct dirent *lv_iter;
++      char uuid[16], *label;
++
++      if (!(d = opendir(DEVICEMAPPERDIR))) {
++              if (errno != ENOENT)
++                      perror("mount (init_dm)");
++              return;
++      }
++
++      while ((lv_iter = readdir(d))) {
++              if (!strcmp(lv_iter->d_name, "control") ||
++                  !strcmp(lv_iter->d_name, ".") ||
++                  !strcmp(lv_iter->d_name, ".."))
++                      continue;
++              snprintf(lvm_device, sizeof(lvm_device), "%s/%s",
++                       DEVICEMAPPERDIR, lv_iter->d_name);
++              if (!get_label_uuid(strdup(lvm_device), &label, uuid))
++                              uuidcache_addentry(strdup(lvm_device),
++                                                 label, uuid);
++      }
++      closedir(d);
++}
++
+ static int
+ uuidcache_init_evms(void) {
+       FILE *procvol;
+@@ -250,6 +281,8 @@
+       fclose(procpt);
+       uuidcache_init_lvm();
++
++      uuidcache_init_dm();
+ }
+ #define UUID   1
diff --git a/util-linux-mtab-lock.patch b/util-linux-mtab-lock.patch
new file mode 100644 (file)
index 0000000..8278f7b
--- /dev/null
@@ -0,0 +1,153 @@
+- Improved /etc/mtab lock
+- fix for the mount command and am-utils using different mtab locking
+
+--- util-linux-2.12p/mount/fstab.c.mtab-lock   2005-03-22 14:05:22.481297072 +0100
++++ util-linux-2.12p/mount/fstab.c     2005-03-22 14:50:55.719781664 +0100
+@@ -395,6 +395,7 @@
+ /* Flag for already existing lock file. */
+ static int we_created_lockfile = 0;
++static int lockfile_fd = -1;
+ /* Flag to indicate that signals have been set up. */
+ static int signals_have_been_setup = 0;
+@@ -416,6 +417,8 @@
+ void
+ unlock_mtab (void) {
+       if (we_created_lockfile) {
++              close(lockfile_fd);
++              lockfile_fd = -1;
+               unlink (MOUNTED_LOCK);
+               we_created_lockfile = 0;
+       }
+@@ -443,7 +446,7 @@
+ void
+ lock_mtab (void) {
+-      int tries = 3;
++      int tries = 100000, i;
+       char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
+       at_die = unlock_mtab;
+@@ -469,45 +472,48 @@
+       sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
++      i = open (linktargetfile, O_WRONLY|O_CREAT, 0);
++      if (i < 0) {
++              int errsv = errno;
++              /* linktargetfile does not exist (as a file)
++                 and we cannot create it. Read-only filesystem?
++                 Too many files open in the system?
++                 Filesystem full? */
++              die (EX_FILEIO, _("can't create lock file %s: %s "
++                                                "(use -n flag to override)"),
++                       linktargetfile, strerror (errsv));
++      }
++      close(i);
++      
+       /* Repeat until it was us who made the link */
+       while (!we_created_lockfile) {
+               struct flock flock;
+-              int errsv, fd, i, j;
+-
+-              i = open (linktargetfile, O_WRONLY|O_CREAT, 0);
+-              if (i < 0) {
+-                      int errsv = errno;
+-                      /* linktargetfile does not exist (as a file)
+-                         and we cannot create it. Read-only filesystem?
+-                         Too many files open in the system?
+-                         Filesystem full? */
+-                      die (EX_FILEIO, _("can't create lock file %s: %s "
+-                           "(use -n flag to override)"),
+-                           linktargetfile, strerror (errsv));
+-              }
+-              close(i);
++              int errsv, j;
+               j = link(linktargetfile, MOUNTED_LOCK);
+               errsv = errno;
+-              (void) unlink(linktargetfile);
+-
+               if (j == 0)
+                       we_created_lockfile = 1;
+               if (j < 0 && errsv != EEXIST) {
++                      (void) unlink(linktargetfile);
+                       die (EX_FILEIO, _("can't link lock file %s: %s "
+                            "(use -n flag to override)"),
+                            MOUNTED_LOCK, strerror (errsv));
+               }
+-              fd = open (MOUNTED_LOCK, O_WRONLY);
++              lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);
+-              if (fd < 0) {
++              if (lockfile_fd < 0) {
+                       int errsv = errno;
+                       /* Strange... Maybe the file was just deleted? */
+-                      if (errno == ENOENT && tries-- > 0)
++                      if (errno == ENOENT && tries-- > 0) {
++                              if (tries % 200 == 0)
++                                      usleep(30);
+                               continue;
++                      }
++                      (void) unlink(linktargetfile);
+                       die (EX_FILEIO, _("can't open lock file %s: %s "
+                            "(use -n flag to override)"),
+                            MOUNTED_LOCK, strerror (errsv));
+@@ -520,7 +526,7 @@
+               if (j == 0) {
+                       /* We made the link. Now claim the lock. */
+-                      if (fcntl (fd, F_SETLK, &flock) == -1) {
++                      if (fcntl (lockfile_fd, F_SETLK, &flock) == -1) {
+                               if (verbose) {
+                                   int errsv = errno;
+                                   printf(_("Can't lock lock file %s: %s\n"),
+@@ -528,13 +534,15 @@
+                               }
+                               /* proceed anyway */
+                       }
++                      (void) unlink(linktargetfile);
+               } else {
+                       static int tries = 0;
+                       /* Someone else made the link. Wait. */
+                       alarm(LOCK_TIMEOUT);
+-                      if (fcntl (fd, F_SETLKW, &flock) == -1) {
++                      if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
+                               int errsv = errno;
++                              (void) unlink(linktargetfile);
+                               die (EX_FILEIO, _("can't lock lock file %s: %s"),
+                                    MOUNTED_LOCK, (errno == EINTR) ?
+                                    _("timed out") : strerror (errsv));
+@@ -542,16 +550,18 @@
+                       alarm(0);
+                       /* Limit the number of iterations - maybe there
+                          still is some old /etc/mtab~ */
+-                      if (tries++ > 3) {
+-                              if (tries > 5)
+-                                      die (EX_FILEIO, _("Cannot create link %s\n"
+-                                          "Perhaps there is a stale lock file?\n"),
+-                                           MOUNTED_LOCK);
+-                              sleep(1);
+-                      }
++                      ++tries;
++                      if (tries % 200 == 0)
++                         usleep(30);
++                      if (tries > 100000) {
++                              (void) unlink(linktargetfile);
++                              close(lockfile_fd);
++                              die (EX_FILEIO, _("Cannot create link %s\n"
++                                                "Perhaps there is a stale lock file?\n"),
++                                       MOUNTED_LOCK);
++                      }
++                      close(lockfile_fd);
+               }
+-
+-              close(fd);
+       }
+ }
diff --git a/util-linux-multibyte.patch b/util-linux-multibyte.patch
new file mode 100644 (file)
index 0000000..e683d90
--- /dev/null
@@ -0,0 +1,281 @@
+- better wide chars usage in the cal command
+- cal not UTF-8-aware
+- more(1) doesn't handle UTF-8 correctly.  In particular, underlining is broken.
+
+--- util-linux-2.13-pre7/include/widechar.h.kzak       2005-08-01 20:18:35.000000000 +0200
++++ util-linux-2.13-pre7/include/widechar.h    2006-03-29 19:38:56.000000000 +0200
+@@ -2,7 +2,7 @@
+ /* This file must be included last because the redefinition of wchar_t may
+    cause conflicts when system include files were included after it. */
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ # include <wchar.h>
+ # include <wctype.h>
+--- util-linux-2.13-pre7/misc-utils/cal.c.kzak 2006-03-29 19:40:26.000000000 +0200
++++ util-linux-2.13-pre7/misc-utils/cal.c      2006-03-29 19:40:34.000000000 +0200
+@@ -355,7 +355,7 @@
+       exit(0);
+ }
+-#ifndef ENABLE_WIDECHAR
++#ifndef HAVE_WIDECHAR
+ static char *eos(char *s) {
+       while (s && *s)
+               s++;
+@@ -366,14 +366,14 @@
+ void headers_init(void)
+ {
+   int i, wd;
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+   wchar_t day_headings_wc[22],j_day_headings_wc[29];
+-  wchar_t wd_wc[10];
++  char *cur_dh = day_headings, *cur_j_dh = j_day_headings;
+ #endif
+   strcpy(day_headings,"");
+   strcpy(j_day_headings,"");
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+   wcscpy(day_headings_wc,L"");
+   wcscpy(j_day_headings_wc,L"");
+ #endif
+@@ -385,30 +385,25 @@
+ #endif
+   for(i = 0 ; i < 7 ; i++ ) {
++     ssize_t space_left;
+      wd = (i + week1stday) % 7;
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+-     mbstowcs(wd_wc,weekday(wd),10);
+-     if (wcswidth(wd_wc,10) < 3)
+-           wcscat(j_day_headings_wc,L" ");
+-     if (wcswidth(wd_wc,10) < 2) {
+-           wcscat(day_headings_wc, L" ");
+-           wcscat(j_day_headings_wc, L" ");
+-     }
+-     wcsncat(day_headings_wc,wd_wc,2);
+-     wcsncat(j_day_headings_wc,wd_wc,3);
+-     wcscat(day_headings_wc, L" ");
+-     wcscat(j_day_headings_wc, L" ");
++     swprintf(day_headings_wc, sizeof(day_headings_wc)/sizeof(day_headings_wc[0]),
++              L"%1.2s ", weekday(wd));
++     swprintf(j_day_headings_wc, sizeof(j_day_headings_wc)/sizeof(j_day_headings_wc[0]),
++              L"%3.3s ", weekday(wd));
++     space_left = sizeof(day_headings)-(cur_dh-day_headings);
++     if(space_left <= 0) break;
++     cur_dh += wcstombs(cur_dh,day_headings_wc, space_left);
++     space_left = sizeof(j_day_headings)-(cur_j_dh-j_day_headings);
++     if(space_left <= 0) break;
++     cur_j_dh +=  wcstombs(cur_j_dh,j_day_headings_wc, space_left);
+ #else
+      sprintf(eos(day_headings), "%2.2s ", weekday(wd));
+      sprintf(eos(j_day_headings), "%3.3s ", weekday(wd));
+ #endif
+   }
+-#ifdef ENABLE_WIDECHAR
+-  wcstombs(day_headings,day_headings_wc,sizeof(day_headings));
+-  wcstombs(j_day_headings,j_day_headings_wc,sizeof(j_day_headings));
+-#endif
+-
+   trim_trailing_spaces(day_headings);
+   trim_trailing_spaces(j_day_headings);
+ #undef weekday
+@@ -718,7 +718,7 @@
+ void
+ center_str(const char* src, char* dest, size_t dest_size, int width)
+ {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       wchar_t str_wc[FMT_ST_CHARS];
+ #endif
+       char str[FMT_ST_CHARS];
+@@ -727,7 +727,7 @@
+       len = strlen(src);
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       if (mbstowcs(str_wc, src, FMT_ST_CHARS) > 0) {
+               wide_char_enabled = 1;
+               len = wcswidth(str_wc, SIZE(str_wc));
+@@ -736,7 +736,7 @@
+       if (len > width) {
+               str_to_print=str;
+               if (wide_char_enabled) {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+                       str_wc[width]=L'\0';
+                       wcstombs(str, str_wc, SIZE(str));
+ #endif
+--- util-linux-2.13-pre7/text-utils/column.c.kzak      2006-03-29 19:41:20.000000000 +0200
++++ util-linux-2.13-pre7/text-utils/column.c   2006-03-29 19:41:25.000000000 +0200
+@@ -52,7 +52,7 @@
+ #include "widechar.h"
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ #define wcs_width(s) wcswidth(s,wcslen(s))
+ static wchar_t *mbs_to_wcs(const char *);
+ #else
+@@ -312,7 +312,7 @@
+       }
+ }
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ static wchar_t *mbs_to_wcs(const char *s)
+ {
+       size_t n;
+@@ -330,7 +330,7 @@
+ }
+ #endif
+-#ifndef ENABLE_WIDECHAR
++#ifndef HAVE_WIDECHAR
+ static char *mtsafe_strtok(char *str, const char *delim, char **ptr)
+ {
+       if (str == NULL) {
+--- util-linux-2.13-pre7/text-utils/pg.c.kzak  2006-03-29 19:41:52.000000000 +0200
++++ util-linux-2.13-pre7/text-utils/pg.c       2006-03-29 19:41:59.000000000 +0200
+@@ -255,7 +255,7 @@
+       usage();
+ }
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ /*
+  * A mbstowcs()-alike function that transparently handles invalid sequences.
+  */
+@@ -402,7 +402,7 @@
+       return 0;
+ }
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ /*
+  * Return the last character that will fit on the line at col columns
+  * in case MB_CUR_MAX > 1.
+@@ -489,7 +489,7 @@
+       unsigned pos = 0;
+       char *t = s;
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       if (MB_CUR_MAX > 1)
+               return endline_for_mb(col, s);
+ #endif
+@@ -776,7 +776,7 @@
+       cmd.count = getcount(cmd.cmdline);
+ }
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ /*
+  * Remove backspace formatting, for searches
+  * in case MB_CUR_MAX > 1.
+@@ -817,7 +817,7 @@
+ {
+       char *p = s, *q;
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       if (MB_CUR_MAX > 1)
+               return colb_for_mb(s);
+ #endif
+@@ -836,7 +836,7 @@
+       return s;
+ }
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ /*
+  * Convert nonprintable characters to spaces
+  * in case MB_CUR_MAX > 1.
+@@ -867,7 +867,7 @@
+ static void
+ makeprint(char *s, size_t l)
+ {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       if (MB_CUR_MAX > 1)
+               return makeprint_for_mb(s, l);
+ #endif
+--- util-linux-2.13-pre7/text-utils/more.c.kzak        2006-03-29 19:41:01.000000000 +0200
++++ util-linux-2.13-pre7/text-utils/more.c     2006-03-29 19:41:08.000000000 +0200
+@@ -782,7 +782,7 @@
+     int       column;
+     static int colflg;
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+     int i;
+     wchar_t wc;
+     int wc_width;
+@@ -805,7 +805,7 @@
+       c = Getc (f);
+     }
+     while (p < &Line[LINSIZ - 1]) {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+       if (fold_opt && use_mbc_buffer_flag && MB_CUR_MAX > 1) {
+           use_mbc_buffer_flag = 0;
+           state_bak = state;
+@@ -923,7 +923,7 @@
+           *length = p - Line;
+           return (column);
+       } else {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+           if (fold_opt && MB_CUR_MAX > 1) {
+               memset (mbc, '\0', MB_LEN_MAX);
+               mbc_pos = 0;
+@@ -1054,7 +1054,23 @@
+                   my_putstring(state ? ULenter : ULexit);
+           }
+           if (c != ' ' || pstate == 0 || state != 0 || ulglitch == 0)
++#ifdef HAVE_WIDECHAR
++          {
++              wchar_t wc;
++              size_t mblength;
++              mbstate_t state;
++              memset (&state, '\0', sizeof (mbstate_t));
++              s--; n++;
++              mblength = mbrtowc (&wc, s, n, &state);
++              if (mblength == (size_t) -2 || mblength == (size_t) -1)
++                      mblength = 1;
++              while (mblength--)
++                      putchar (*s++);
++              n += mblength;
++          }
++#else
+               putchar(c);
++#endif
+           if (state && *chUL) {
+               pr(chBS);
+               my_putstring(chUL);
+@@ -1867,7 +1867,7 @@
+       }
+       else if (((cc_t) c == otty.c_cc[VERASE]) && !slash) {
+           if (sp > buf) {
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+               if (MB_CUR_MAX > 1)
+                 {
+                   wchar_t wc;
+--- util-linux-2.13-pre7/text-utils/ul.c.kzak  2006-03-29 19:42:09.000000000 +0200
++++ util-linux-2.13-pre7/text-utils/ul.c       2006-03-29 19:42:25.000000000 +0200
+@@ -50,7 +50,7 @@
+ #include "widechar.h"
+-#ifdef ENABLE_WIDECHAR
++#ifdef HAVE_WIDECHAR
+ static int put1wc(int c) /* Output an ASCII character as a wide character */
+ {
+   if (putwchar(c) == WEOF)
diff --git a/util-linux-namei-logic.patch b/util-linux-namei-logic.patch
new file mode 100644 (file)
index 0000000..723be82
--- /dev/null
@@ -0,0 +1,132 @@
+- namei ignores non-directory components instead of saying "Not a directory"
+- namei enforces symlink limits inconsistently
+
+--- util-linux-2.13-pre7/misc-utils/namei.1.nodir      2006-12-15 10:58:38.000000000 +0100
++++ util-linux-2.13-pre7/misc-utils/namei.1    2006-12-15 10:58:51.000000000 +0100
+@@ -52,9 +52,5 @@
+ Roger Southwick  (rogers@amadeus.wr.tek.com)
+ .SH BUGS
+ To be discovered.
+-.SH CAVEATS
+-.I Namei
+-will follow an infinite loop of symbolic links forever.  To escape, use
+-SIGINT (usually ^C).
+ .SH "SEE ALSO"
+ ls(1), stat(1)
+--- util-linux-2.13-pre7/misc-utils/namei.c.nodir      2006-12-14 21:38:41.000000000 +0100
++++ util-linux-2.13-pre7/misc-utils/namei.c    2006-12-15 10:58:31.000000000 +0100
+@@ -42,6 +42,10 @@
+ 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+ - added Native Language Support
++2006-12-15 Karel Zak <kzak@redhat.com> 
++- fixed logic; don't follow the path if a component is not directory
++- fixed infinite loop of symbolic links; stack size is very limited
++
+ -------------------------------------------------------------*/
+ #include <stdio.h>
+@@ -66,7 +70,7 @@
+ #endif
+ static char *pperm(unsigned short);
+-static void namei(char *, int);
++static void namei(char *, int, mode_t *);
+ static void usage(void);
+ int
+@@ -107,9 +111,10 @@
+     for(; optind < argc; optind++){
++      mode_t lastmode = 0;
+       (void)printf("f: %s\n", argv[optind]);
+       symcount = 1;
+-      namei(argv[optind], 0);
++      namei(argv[optind], 0, &lastmode);
+       if(chdir(curdir) == -1){
+           (void)fprintf(stderr,
+@@ -131,8 +136,10 @@
+ #define NODEV         (dev_t)(-1)
+ #endif
++int kzak;
++
+ static void
+-namei(char *file, int lev) {
++namei(char *file, int lev, mode_t *lastmode) {
+     char *cp;
+     char buf[BUFSIZ], sym[BUFSIZ];
+     struct stat stb;
+@@ -143,7 +150,7 @@
+      * See if the file has a leading /, and if so cd to root
+      */
+     
+-    if(*file == '/'){
++    if(file && *file == '/'){
+       while(*file == '/')
+           file++;
+       
+@@ -166,7 +173,7 @@
+           (void)printf(" d /\n");
+     }
+-    for(;;){
++    for(; file && *file;){
+       if (strlen(file) >= BUFSIZ) {
+               fprintf(stderr,_("namei: buf overflow\n"));
+@@ -198,6 +205,20 @@
+       for(i = 0; i < lev; i++)
+           (void)printf("  ");
++
++      /*
++       * Previous element in the path wasn't directory, it means 
++       * we cannot walk on *path*  and check the actual element by lstat(), because
++       * there could be a component with same name. Try:
++       *
++       * $ touch a b
++       * $ namei a/b    <-- "a" is not directory so namei shouldn't check for "b"
++       */
++      if (*lastmode && S_ISDIR(*lastmode)==0 && S_ISLNK(*lastmode)==0){
++          (void)printf(" ? %s - %s (%d)\n", buf, strerror(ENOENT), ENOENT);
++          return;
++      }
++
+       /*
+        * See what type of critter this file is
+        */
+@@ -207,6 +228,8 @@
+           return;
+       }
++      *lastmode = stb.st_mode;
++
+       switch(stb.st_mode & S_IFMT){
+           case S_IFDIR:
+@@ -241,7 +264,6 @@
+                * Sigh, another symlink.  Read its contents and
+                * call namei()
+                */
+-              
+               bzero(sym, BUFSIZ);
+               if(readlink(buf, sym, BUFSIZ) == -1){
+                   (void)printf(_(" ? problems reading symlink %s - %s (%d)\n"), buf, ERR);
+@@ -255,11 +277,12 @@
+               if(symcount > 0 && symcount++ > MAXSYMLINKS){
+                   (void)printf(_("  *** EXCEEDED UNIX LIMIT OF SYMLINKS ***\n"));
+-                  symcount = -1;
+               } else {
+                   (void)printf("\n");
+-                  namei(sym, lev + 1);
++                  namei(sym, lev + 1, lastmode);
+               }
++              if (symcount > MAXSYMLINKS)
++                  return;
+               break;
+           case S_IFCHR:
diff --git a/util-linux-pamsession.patch b/util-linux-pamsession.patch
new file mode 100644 (file)
index 0000000..fec5bca
--- /dev/null
@@ -0,0 +1,14 @@
+- Incomplete PAM session support in the login command 
+
+diff -urb util-linux-2.12a.orig/login-utils/login.c util-linux-2.12a/login-utils/login.c
+--- util-linux-2.12a.orig/login-utils/login.c  2005-04-08 09:43:37.000000000 -0400
++++ util-linux-2.12a/login-utils/login.c       2005-04-08 11:14:37.850579656 -0400
+@@ -703,6 +703,8 @@
+     PAM_FAIL_CHECK;
+     retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
++    if (retcode != PAM_SUCCESS)
++          pam_close_session(pamh, 0);
+     PAM_FAIL_CHECK;
+ #else /* ! USE_PAM */
diff --git a/util-linux-partx-man.patch b/util-linux-partx-man.patch
new file mode 100644 (file)
index 0000000..ff1d023
--- /dev/null
@@ -0,0 +1,129 @@
+--- util-linux-2.13-pre7/partx/Makefile.am.kzak        2007-01-11 16:30:39.000000000 +0100
++++ util-linux-2.13-pre7/partx/Makefile.am     2007-01-11 16:30:30.000000000 +0100
+@@ -4,5 +4,6 @@
+ usrsbinexec_PROGRAMS = addpart delpart partx
+ partx_SOURCES = bsd.c dos.c partx.c solaris.c unixware.c gpt.c crc32.c
++man_MANS = addpart.8 delpart.8 partx.8
+ endif
+--- /dev/null  2007-01-05 11:17:33.335119060 +0100
++++ util-linux-2.13-pre7/partx/delpart.8       2007-01-11 16:28:37.000000000 +0100
+@@ -0,0 +1,30 @@
++.\" delpart.8 -- 
++.\" Copyright 2007 Karel Zak <kzak@redhat.com> 
++.\" Copyright 2007 Red Hat, Inc.
++.\" May be distributed under the GNU General Public License
++.TH DELPART 8 "11 Jan 2007"
++.SH NAME
++delpart \- 
++simple wrapper around the "del partition" ioctl
++.SH SYNOPSIS
++.B delpart device partition
++.SH DESCRIPTION
++.B delpart
++is a program that asks the Linux kernel to remove a partition.
++
++This command doesn't manipulate with partitions on hard drive.
++
++.SH OPTIONS
++.TP
++.BI device 
++Specify the disk device.
++.TP
++.BI partition
++Specify the partition number.
++
++.SH SEE ALSO
++.BR addpart (8),
++.BR fdisk (8),
++.BR parted (8),
++.BR partprobe (8),
++.BR partx (8)
+--- /dev/null  2007-01-05 11:17:33.335119060 +0100
++++ util-linux-2.13-pre7/partx/addpart.8       2007-01-11 16:28:37.000000000 +0100
+@@ -0,0 +1,36 @@
++.\" addpart.8 -- 
++.\" Copyright 2007 Karel Zak <kzak@redhat.com> 
++.\" Copyright 2007 Red Hat, Inc.
++.\" May be distributed under the GNU General Public License
++.TH ADDPART 8 "11 Jan 2007"
++.SH NAME
++addpart \- 
++simple wrapper around the "add partition" ioctl
++.SH SYNOPSIS
++.B addpart device partition start length
++.SH DESCRIPTION
++.B addpart
++is a program that informs the Linux kernel of new partition.
++
++This command doesn't manipulate with partitions on hard drive.
++
++.SH PARAMETERS
++.TP
++.BI device 
++Specify the disk device.
++.TP
++.BI partition
++Specify the partition number.
++.TP
++.BI start
++Specify the begin of the partition (in bytes).
++.TP
++.BI length
++Specify the length of the partition (in bytes).
++
++.SH SEE ALSO
++.BR delpart (8),
++.BR fdisk (8),
++.BR parted (8),
++.BR partprobe (8),
++.BR partx (8)
+--- /dev/null  2007-01-05 11:17:33.335119060 +0100
++++ util-linux-2.13-pre7/partx/partx.8 2007-01-11 16:28:37.000000000 +0100
+@@ -0,0 +1,45 @@
++.\" partx.8 -- 
++.\" Copyright 2007 Karel Zak <kzak@redhat.com> 
++.\" Copyright 2007 Red Hat, Inc.
++.\" May be distributed under the GNU General Public License
++.TH PARTX 8 "11 Jan 2007"
++.SH NAME
++partx \- 
++telling the kernel about presence and numbering of on-disk partitions.
++.SH SYNOPSIS
++.B partx [-a|-d|-l] [--type TYPE] [--nr M-N] [partition] disk
++.SH DESCRIPTION
++Given a block device (
++.B disk
++) and a partition table 
++.B type 
++, try to parse the partition table, and list the
++contents. Optionally add or remove partitions.
++
++This is not an fdisk - adding and removing partitions
++is not a change of the disk, but just telling the kernel
++about presence and numbering of on-disk partitions.
++
++.SH OPTIONS
++.TP 
++.B \-a
++add specified partitions or read disk and add all partitions
++.TP
++.B \-d
++delete specified or all partitions
++.TP
++.B \-l
++list partitions
++.TP
++.BI --type " TYPE"
++Specify the partition type -- dos, bsd, solaris, unixware or gpt.
++.TP 
++.BI --nr " M-N"
++Specify the range of partitions (e.g --nr 2-4).
++
++.SH SEE ALSO
++.BR addpart (8),
++.BR delpart (8),
++.BR fdisk (8),
++.BR parted (8),
++.BR partprobe (8)
diff --git a/util-linux-procpartitions.patch b/util-linux-procpartitions.patch
new file mode 100644 (file)
index 0000000..3c27c36
--- /dev/null
@@ -0,0 +1,76 @@
+Mount has to read /proc/partitions in one gulp. It doesn't. Failed for me 
+after a hard powerdown (oops) and the resulting fsck-the-world frenzy on 
+startup, before the mount -a. Falure cause is identical (getting out of 
+sync with the text at the 1K boundary), but failure mode not quite so 
+drastic as it doesn't bail out like fsck does.
+
+--- util-linux-2.11y/disk-utils/blockdev.c.procpartitions      2002-03-08 17:57:02.000000000 -0500
++++ util-linux-2.11y/disk-utils/blockdev.c     2003-01-13 14:28:41.000000000 -0500
+@@ -290,6 +290,7 @@
+       char ptname[200];
+       char device[210];
+       int ma, mi, sz;
++      char iobuf[32*1024];
+       procpt = fopen(PROC_PARTITIONS, "r");
+       if (!procpt) {
+@@ -297,6 +298,7 @@
+                       progname, PROC_PARTITIONS);
+               exit(1);
+       }
++      setvbuf(procpt, iobuf, _IOFBF, sizeof(iobuf));
+       while (fgets(line, sizeof(line), procpt)) {
+               if (sscanf (line, " %d %d %d %[^\n ]",
+--- util-linux-2.11y/fdisk/fdisk.c.procpartitions      2003-01-13 14:28:41.000000000 -0500
++++ util-linux-2.11y/fdisk/fdisk.c     2003-01-13 14:28:41.000000000 -0500
+@@ -2371,12 +2371,14 @@
+       FILE *procpt;
+       char line[100], ptname[100], devname[120], *s;
+       int ma, mi, sz;
++      char iobuf[32*1024];
+       procpt = fopen(PROC_PARTITIONS, "r");
+       if (procpt == NULL) {
+               fprintf(stderr, _("cannot open %s\n"), PROC_PARTITIONS);
+               return;
+       }
++      setvbuf(procpt, iobuf, _IOFBF, sizeof(iobuf));
+       while (fgets(line, sizeof(line), procpt)) {
+               if (sscanf (line, " %d %d %d %[^\n ]",
+--- util-linux-2.11y/mount/mount_by_label.c.procpartitions     2002-11-26 04:23:49.000000000 -0500
++++ util-linux-2.11y/mount/mount_by_label.c    2003-01-13 14:31:53.000000000 -0500
+@@ -136,9 +136,7 @@
+       char device[110];
+       int firstPass;
+       int handleOnFirst;
+-#if 0
+       char iobuf[32*1024];    /* For setvbuf */
+-#endif
+       if (uuidCache)
+               return;
+@@ -155,7 +153,6 @@
+                      PROC_PARTITIONS);
+               return;
+       }
+-#if 0
+ /* Ugly kludge - the contents of /proc/partitions change in time,
+    and this causes failures when the file is not read in one go.
+    In particular, one cannot use stdio on /proc/partitions.
+@@ -166,9 +163,12 @@
+    to keep statistics in /proc/partitions. Of course, statistics belong
+    in some /proc/diskstats, not in some /proc file that happened to
+    exist already. */
+-
++/* Until someone actually implements something else, /proc/partitions _IS_ 
++   /proc/diskstats. And no matter what file we are reading, we will still 
++   need to increase the buffer size, because 8k is just not Enough For 
++   Everyone even if stats aren't in /proc/partitions.
++*/
+       setvbuf(procpt, iobuf, _IOFBF, sizeof(iobuf));
+-#endif
+       for (firstPass = 1; firstPass >= 0; firstPass--) {
+           fseek(procpt, 0, SEEK_SET);
diff --git a/util-linux-raw-handle-nonpresent-devs.patch b/util-linux-raw-handle-nonpresent-devs.patch
new file mode 100644 (file)
index 0000000..e4b0098
--- /dev/null
@@ -0,0 +1,75 @@
+Allow raw(8) to bind raw devices whose device nodes do not yet exist
+
+--- util-linux-2.12a/disk-utils/raw.c.=K0000=.orig
++++ util-linux-2.12a/disk-utils/raw.c
+@@ -31,6 +31,7 @@
+ #endif
+ #define DEVFS_RAWCTLDEV "/dev/raw/rawctl"
++#define RAW_NR_MINORS 8192
+ char *        progname;
+ int   do_query = 0;
+@@ -94,7 +95,7 @@ int main(int argc, char *argv[])
+       if (do_query_all) {
+               if (optind < argc)
+                       usage(1);
+-              for (i=1; i<255; i++)
++              for (i = 1; i < RAW_NR_MINORS; i++)
+                       query(i, 1);
+               exit(0);
+       }
+@@ -109,9 +110,16 @@ int main(int argc, char *argv[])
+       err = stat(raw_name, &statbuf);
+       if (err) {
+-              fprintf (stderr, "Cannot locate raw device '%s' (%s)\n",
+-                       raw_name, strerror(errno));
+-              exit(2);
++              int rc;
++              
++              rc = sscanf(raw_name, RAWDEVDIR "raw%d", &raw_minor);
++              if (rc != 1) {
++                      fprintf (stderr, 
++                               "Cannot locate raw device '%s' (%s)\n",
++                               raw_name, strerror(errno));
++                      exit(2);
++              }
++              goto skip_test_rawdev;
+       }
+       
+       if (!S_ISCHR(statbuf.st_mode)) {
+@@ -127,6 +135,7 @@ int main(int argc, char *argv[])
+       raw_minor = minor(statbuf.st_rdev);
++skip_test_rawdev:
+       if (do_query)
+               return query(raw_minor, 0);
+       
+@@ -193,6 +202,7 @@ void open_raw_ctl(void)
+ int query(int minor, int quiet)
+ {
+       struct raw_config_request rq;
++      static int has_worked = 0;
+       int err;
+       
+       rq.raw_minor = minor;
+@@ -200,11 +210,17 @@ int query(int minor, int quiet)
+       if (err < 0) {
+               if (quiet && errno == ENODEV)
+                       return 3;
++              if (has_worked && errno == EINVAL)
++                      return 0;
+               fprintf (stderr, 
+                        "Error querying raw device (%s)\n",
+                        strerror(errno));
+               exit(3);
+       }
++      /* If one query has worked, mark that fact so that we don't
++       * report spurious fatal errors if raw(8) has been built to
++       * support more raw minor numbers than the kernel has. */
++      has_worked = 1;
+       if (quiet && !rq.block_major && !rq.block_minor)
+               return 0;
+       printf (RAWDEVDIR "raw%d:       bound to major %d, minor %d\n",
diff --git a/util-linux-raw-man.patch b/util-linux-raw-man.patch
new file mode 100644 (file)
index 0000000..08a4eb2
--- /dev/null
@@ -0,0 +1,40 @@
+--- util-linux-2.11f/disk-utils/raw.8.sopwith  Tue Feb 26 13:15:34 2002
++++ util-linux-2.11f/disk-utils/raw.8  Tue Feb 26 13:16:28 2002
+@@ -15,6 +15,12 @@
+ .PP
+ .B raw
+ .B \-qa
++.SH WARNING
++Although Linux includes support for rawio, it is now a deprecated interface. If
++your application performs device access using this interface, Red Hat
++encourages you to modify your application to open the block device with the
++O_DIRECT flag. The rawio interface is a candidate for removal from future releases.
++ 
+ .SH DESCRIPTION
+ .B raw
+ is used to bind a Linux raw character device to a block device.  Any
+@@ -58,6 +58,11 @@
+ disk, they must be an exact number of sectors long, and the data buffer
+ in virtual memory must also be aligned to a multiple of the sector
+ size.  The sector size is 512 bytes for most devices.
++.PP
++Use the /etc/sysconfig/rawdevices file to define the set of raw device
++mappings automatically created during the system startup sequence. The
++format of the file is the same used in the command line with the exception
++that the "raw" command itself is omitted.
+ .SH OPTIONS
+ .TP
+ .B -q
+@@ -82,8 +88,10 @@
+ .SH BUGS
+ The Linux 
+ .B dd
+-(1) command does not currently align its buffers correctly, and so
+-cannot be used on raw devices.
++(1) command should be used without bs= option or the blocksize needs to be a
++multiple of the sector size of the device (512 bytes usually) otherwise it
++will fail with "Invalid Argument" messages (EINVAL).
++
+ .PP
+ Raw I/O devices do not maintain cache coherency with the Linux block
+ device buffer cache.  If you use raw I/O to overwrite data already in
diff --git a/util-linux-raw-raw0.patch b/util-linux-raw-raw0.patch
new file mode 100644 (file)
index 0000000..ea931cd
--- /dev/null
@@ -0,0 +1,47 @@
+- issues with raw device support ("raw0" is wrong device name)
+
+--- util-linux-2.13-pre6/disk-utils/raw.c.kzak 2006-11-21 21:56:40.000000000 +0100
++++ util-linux-2.13-pre6/disk-utils/raw.c      2006-11-21 22:35:11.000000000 +0100
+@@ -66,6 +66,7 @@
+       int  err;
+       int  block_major, block_minor;  
+       int  i;
++      int  rc;
+       struct stat statbuf;
+       
+@@ -108,19 +109,23 @@
+               usage(1);
+       raw_name = argv[optind++];
++      rc = sscanf(raw_name, RAWDEVDIR "raw%d", &raw_minor);
++      if (rc != 1) {
++              fprintf (stderr, 
++                       "Unsupported raw device name '%s' (format is " RAWDEVDIR "rawN))\n",
++                       raw_name);
++              exit(2);
++      }
++      if (raw_minor == 0) {
++              fprintf (stderr,
++                      "Unsupported raw device name '%s' (minor number cannot be zero)\n",
++                      raw_name);
++              exit(2);
++      }
++
+       err = stat(raw_name, &statbuf);
+-      if (err) {
+-              int rc;
+-              
+-              rc = sscanf(raw_name, RAWDEVDIR "raw%d", &raw_minor);
+-              if (rc != 1) {
+-                      fprintf (stderr, 
+-                               "Cannot locate raw device '%s' (%s)\n",
+-                               raw_name, strerror(errno));
+-                      exit(2);
+-              }
++      if (err) 
+               goto skip_test_rawdev;
+-      }
+       
+       if (!S_ISCHR(statbuf.st_mode)) {
+               fprintf (stderr, "raw device '%s' is not a character dev\n",
diff --git a/util-linux-rdev-man.patch b/util-linux-rdev-man.patch
new file mode 100644 (file)
index 0000000..817888d
--- /dev/null
@@ -0,0 +1,20 @@
+--- util-linux-2.12a/sys-utils/rdev.8.sopwith  2004-08-20 11:35:56.740842004 -0400
++++ util-linux-2.12a/sys-utils/rdev.8  2004-08-20 11:38:38.291622818 -0400
+@@ -79,7 +79,8 @@
+ .B ramsize
+ command, the
+ .B size
+-parameter specifies the size of the RAM disk in kilobytes.
++parameter specifies the size of the RAM disk in kilobytes. 2.0.x kernels and newer dynamically allocate the ramdisk 
++and do not need this setting.
+ For the
+ .B rootflags
+@@ -121,6 +122,7 @@
+ .B rdev
+ to act like
+ .BR ramsize .
++(Not relevant for 2.0.x and newer kernels.)
+ .TP
+ .B \-R
+ Causes
diff --git a/util-linux-schedutils-SCHED_BATCH.patch b/util-linux-schedutils-SCHED_BATCH.patch
new file mode 100644 (file)
index 0000000..0377e72
--- /dev/null
@@ -0,0 +1,104 @@
+- SCHED_BATCH option missing in chrt
+
+--- util-linux-2.13-pre6/schedutils/chrt.1.batch       2006-11-10 13:23:37.000000000 -0500
++++ util-linux-2.13-pre6/schedutils/chrt.1     2006-11-10 13:27:23.000000000 -0500
+@@ -36,10 +36,11 @@
+ .BR chrt (1)
+ sets or retrieves the real-time scheduling attributes of an existing PID or
+ runs COMMAND with the given attributes.  Both policy (one of
++.BR SCHED_OTHER ,
+ .BR SCHED_FIFO ,
+ .BR SCHED_RR ,
+ or
+-.BR SCHED_OTHER )
++.BR SCHED_BATCH )
+ and priority can be set and retrieved.
+ .SH OPTIONS
+ .TP
+@@ -48,6 +49,10 @@
+ .TP
+ .TP
++.B -b, --batch
++set scheduling policy to
++.BR SCHED_BATCH
++.TP
+ .B -f, --fifo
+ set scheduling policy to
+ .BR SCHED_FIFO
+--- util-linux-2.13-pre6/schedutils/chrt.c.batch       2005-08-14 11:18:54.000000000 -0400
++++ util-linux-2.13-pre6/schedutils/chrt.c     2006-11-10 13:27:52.000000000 -0500
+@@ -36,6 +36,8 @@
+       fprintf(stderr, "usage: %s [options] [prio] [pid | cmd [args...]]\n",
+                       cmd);
+       fprintf(stderr, "manipulate real-time attributes of a process\n");
++      fprintf(stderr, "  -b, --batch                        "
++                      "set policy to SCHED_BATCH\n");
+       fprintf(stderr, "  -f, --fifo                         "
+                       "set policy to SCHED_FF\n");
+       fprintf(stderr, "  -p, --pid                          "
+@@ -83,6 +85,9 @@
+       case SCHED_RR:
+               printf("SCHED_RR\n");
+               break;
++      case SCHED_BATCH:
++              printf("SCHED_BATCH\n");
++              break;
+       default:
+               printf("unknown\n");
+       }
+@@ -101,6 +106,13 @@
+ {
+       int max, min;
++      max = sched_get_priority_max(SCHED_OTHER);
++      min = sched_get_priority_min(SCHED_OTHER);
++      if (max >= 0 && min >= 0)
++              printf("SCHED_OTHER min/max priority\t: %d/%d\n", min, max);
++      else
++              printf("SCHED_OTHER not supported?\n");
++
+       max = sched_get_priority_max(SCHED_FIFO);
+       min = sched_get_priority_min(SCHED_FIFO);
+       if (max >= 0 && min >= 0)
+@@ -115,12 +127,12 @@
+       else
+               printf("SCHED_RR not supported?\n");
+-      max = sched_get_priority_max(SCHED_OTHER);
+-      min = sched_get_priority_min(SCHED_OTHER);
++      max = sched_get_priority_max(SCHED_BATCH);
++      min = sched_get_priority_min(SCHED_BATCH);
+       if (max >= 0 && min >= 0)
+-              printf("SCHED_OTHER min/max priority\t: %d/%d\n", min, max);
++              printf("SCHED_BATCH min/max priority\t: %d/%d\n", min, max);
+       else
+-              printf("SCHED_OTHER not supported?\n");
++              printf("SCHED_BATCH not supported?\n");
+ }
+ int main(int argc, char *argv[])
+@@ -130,6 +142,7 @@
+       pid_t pid = 0;
+       struct option longopts[] = {
++              { "batch",      0, NULL, 'b' },
+               { "fifo",       0, NULL, 'f' },
+               { "pid",        0, NULL, 'p' },
+               { "help",       0, NULL, 'h' },
+@@ -141,11 +154,14 @@
+               { NULL,         0, NULL, 0 }
+       };
+-      while((i = getopt_long(argc, argv, "+fphmorvV", longopts, NULL)) != -1)
++      while((i = getopt_long(argc, argv, "+bfphmorvV", longopts, NULL)) != -1)
+       {
+               int ret = 1;
+               switch (i) {
++              case 'b':
++                      policy = SCHED_BATCH;
++                      break;
+               case 'f':
+                       policy = SCHED_FIFO;
+                       break;
diff --git a/util-linux-schedutils-man.patch b/util-linux-schedutils-man.patch
new file mode 100644 (file)
index 0000000..c525388
--- /dev/null
@@ -0,0 +1,24 @@
+- broken example in man pages
+
+--- util-linux-2.13-pre6/schedutils/taskset.1.kzak     2006-02-22 16:10:26.000000000 +0100
++++ util-linux-2.13-pre6/schedutils/taskset.1  2006-02-22 16:10:38.000000000 +0100
+@@ -82,7 +82,7 @@
+ .SH USAGE
+ .TP
+ The default behavior is to run a new command with a given affinity mask:
+-taskset [mask] -- [command] [arguments]
++taskset [mask] [command] [arguments]
+ .TP
+ You can also retrieve the CPU affinity of an existing task:
+ taskset -p [pid]
+--- util-linux-2.13-pre6/schedutils/chrt.1.kzak        2006-02-22 16:09:02.000000000 +0100
++++ util-linux-2.13-pre6/schedutils/chrt.1     2006-02-22 16:09:22.000000000 +0100
+@@ -72,7 +72,7 @@
+ .SH USAGE
+ .TP
+ The default behavior is to run a new command::
+-chrt [prio] -- [command] [arguments]
++chrt [prio] [command] [arguments]
+ .TP
+ You can also retrieve the real-time attributes of an existing task:
+ chrt -p [pid]
diff --git a/util-linux-skipraid2.patch b/util-linux-skipraid2.patch
new file mode 100644 (file)
index 0000000..870df11
--- /dev/null
@@ -0,0 +1,112 @@
+A RAID1 device cannot be mounted using its LABEL in /etc/fstab: mount says
+there's more than one partition with that label and bails out.
+
+--- util-linux-2.11y/mount/linux_fs.h.skipraid2        2002-10-07 09:08:22.000000000 -0400
++++ util-linux-2.11y/mount/linux_fs.h  2003-01-13 14:42:57.000000000 -0500
+@@ -13,6 +13,12 @@
+ #endif
+ #endif
++#include <inttypes.h>
++#ifndef BLKGETSIZE64
++#include <sys/ioctl.h>
++#define BLKGETSIZE64 _IOR(0x12,114,sizeof(uint64_t))
++#endif
++
+ #define MINIX_SUPER_MAGIC   0x137F         /* minix v1, 14 char names */
+ #define MINIX_SUPER_MAGIC2  0x138F         /* minix v1, 30 char names */
+ #define MINIX2_SUPER_MAGIC  0x2468       /* minix v2, 14 char names */
+--- util-linux-2.11y/mount/get_label_uuid.c.skipraid2  2003-01-13 14:44:04.000000000 -0500
++++ util-linux-2.11y/mount/get_label_uuid.c    2003-01-13 14:46:34.000000000 -0500
+@@ -6,6 +6,8 @@
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <endian.h>
++#include <sys/stat.h>
+ #include "linux_fs.h"
+ #include "get_label_uuid.h"
+@@ -19,28 +21,62 @@
+  *  not on the disks that form the raid array. This test causes a lot of
+  *  problems when run on my striped promise fasttrak 100 array."
+  */
+-static inline int
+-is_raid_partition(int fd) {
+-#if 0
+-      struct mdp_super_block mdsb;
+-      int n;
+-
+-      /* hardcode 4096 here in various places, because that's
+-         what it's defined to be.  Note that even if we used
+-         the actual kernel headers, sizeof(mdp_super_t) is
+-         slightly larger in the 2.2 kernel on 64-bit archs,
+-         so using that wouldn't work. */
+-      lseek(fd, -4096, SEEK_END);     /* Ignore possible error
+-                                         about return value overflow */
+-      n = 4096;
+-      if (sizeof(mdsb) < n)
+-              n = sizeof(mdsb);
+-      if (read(fd, &mdsb, n) != n)
+-              return 1;               /* error */
+-      return (mdsbmagic(mdsb) == MD_SB_MAGIC);
++
++#if BYTE_ORDER == BIG_ENDIAN
++#define INT32_FROM_LE(val)        ((unsigned int) ( \
++    (((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \
++    (((unsigned int) (val) & (unsigned int) 0x0000ff00U) <<  8) | \
++    (((unsigned int) (val) & (unsigned int) 0x00ff0000U) >>  8) | \
++    (((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24)))
+ #else
+-      return 0;
++#define INT32_FROM_LE(val) (val)
++#endif
++
++typedef struct {
++      unsigned int md_magic;
++} mdp_super_t;
++#ifndef MD_SB_MAGIC
++#define MD_SB_MAGIC           0xa92b4efc
++#endif
++#ifndef MD_RESERVED_BYTES
++#define MD_RESERVED_BYTES 65536L
+ #endif
++#ifndef MD_NEW_SIZE_BYTES
++#define MD_NEW_SIZE_BYTES(x)          ((x & ~(MD_RESERVED_BYTES - 1L)) - MD_RESERVED_BYTES)
++#endif
++
++static int
++is_raid_partition(int fd)
++{
++        mdp_super_t mdsb;
++        int n;
++      struct stat sbuf;
++      if(fstat(fd, &sbuf))
++        return 2;
++      if(!sbuf.st_size) {
++              uint64_t bsize64;
++              unsigned int bsize32;
++              if(!ioctl(fd, BLKGETSIZE64, &bsize64))
++                      sbuf.st_size = bsize64;
++              else if(!ioctl(fd, BLKGETSIZE, &bsize32))
++                      sbuf.st_size = bsize32;
++      }
++      if(!sbuf.st_size) return 3;
++      /* hardcode 4096 here in various places,
++         because that's what it's defined to be.
++         Note that even if we used the actual kernel headers,
++         sizeof(mdp_super_t) is slightly larger in the 2.2 kernel on 64-bit
++         archs, so using that wouldn't work. */
++      lseek(fd, MD_NEW_SIZE_BYTES(sbuf.st_size), SEEK_SET);
++      n = 4096; if(sizeof(mdsb) < n) n = sizeof(mdsb);
++        if(read(fd, &mdsb, n) != n)
++        return 4; /* error */
++      mdsb.md_magic = INT32_FROM_LE(mdsb.md_magic);
++      return (mdsb.md_magic == MD_SB_MAGIC); /* If this device has a
++                                                RAID superblock at
++                                                the end, it must be
++                                                part of a RAID
++                                                array. */
+ }
+ /* for now, only ext2, ext3, xfs, ocfs are supported */
diff --git a/util-linux-swap-page.patch b/util-linux-swap-page.patch
new file mode 100644 (file)
index 0000000..40b6374
--- /dev/null
@@ -0,0 +1,70 @@
+Don't use asm/page.h
+
+--- util-linux-2.13-pre6/disk-utils/mkswap.c.page      2006-06-12 17:30:57.000000000 +0200
++++ util-linux-2.13-pre6/disk-utils/mkswap.c   2006-06-12 17:30:31.000000000 +0200
+@@ -53,17 +53,6 @@
+ #include <uuid/uuid.h>
+ #endif
+-/* Try to get PAGE_SIZE from libc or kernel includes */
+-#ifdef HAVE_SYS_USER_H
+-                              /* Note: <sys/user.h> says: for gdb only */
+-#include <sys/user.h>         /* for PAGE_SIZE and PAGE_SHIFT */
+-#else
+-#ifdef HAVE_ASM_PAGE_H
+-#include <asm/page.h>         /* for PAGE_SIZE and PAGE_SHIFT */
+-                              /* we also get PAGE_SIZE via getpagesize() */
+-#endif
+-#endif
+-
+ #ifndef _IO
+ /* pre-1.3.45 */
+ #define BLKGETSIZE 0x1260
+@@ -172,10 +161,6 @@
+ static void
+ init_signature_page(void) {
+-
+-#ifdef PAGE_SIZE
+-      defined_pagesize = PAGE_SIZE;
+-#endif
+       kernel_pagesize = getpagesize();
+       pagesize = kernel_pagesize;
+--- util-linux-2.13-pre6/configure.ac.page     2006-06-12 17:28:51.000000000 +0200
++++ util-linux-2.13-pre6/configure.ac  2006-06-12 17:28:28.000000000 +0200
+@@ -26,7 +26,8 @@
+ ])
+ AC_CHECK_HEADERS(langinfo.h)
+ AC_CHECK_HEADERS(sys/user.h)
+-AC_CHECK_HEADERS(asm/page.h)
++# Suck ...
++#AC_CHECK_HEADERS(asm/page.h)
+ AC_CHECK_HEADERS(rpcsvc/nfs_prot.h)
+ AC_CHECK_HEADERS(sys/io.h)
+ AC_CHECK_HEADERS(pty.h)
+--- util-linux-2.13-pre6/mount/swap.configure.page     2006-06-12 17:23:27.000000000 +0200
++++ util-linux-2.13-pre6/mount/swap.configure  2006-06-12 17:25:28.000000000 +0200
+@@ -3,7 +3,7 @@
+ # Prepare test
+ CC=${CC-cc}
+-compile="$CC -o conftest conftest.c >/dev/null 2>&1"
++compile="$CC -o conftest conftest.c"
+ rm -f conftest conftest.c swapargs.h
+ # What include files shall we try?
+@@ -14,9 +14,10 @@
+ PAGEH=
+ if [ -f /usr/include/sys/swap.h ]; then
+       SWAPH="#include <sys/swap.h>"
+-      if [ -f /usr/include/asm/page.h ]; then
+-              PAGEH="#include <asm/page.h>"
+-      fi
++      # Suck ...
++      #if [ -f /usr/include/asm/page.h ]; then
++      #       PAGEH="#include <asm/page.h>"
++      #fi
+ fi
+ echo $PAGEH > conftest.c
+ echo $SWAPH >> conftest.c
diff --git a/util-linux-swapon-suspend.patch b/util-linux-swapon-suspend.patch
new file mode 100644 (file)
index 0000000..5f8864f
--- /dev/null
@@ -0,0 +1,163 @@
+- swsusp swaps should be reinitialized
+
+--- util-linux-2.13-pre2/mount/swapon.c.swsuspend      2005-09-02 14:32:53.000000000 +0200
++++ util-linux-2.13-pre2/mount/swapon.c        2005-09-02 16:29:43.000000000 +0200
+@@ -11,6 +11,9 @@
+ #include <mntent.h>
+ #include <errno.h>
+ #include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/wait.h>
++#include <fcntl.h>
+ #include "xmalloc.h"
+ #include "swap_constants.h"
+ #include "swapargs.h"
+@@ -22,6 +25,7 @@
+ #define       _PATH_FSTAB     "/etc/fstab"
+ #define PROC_SWAPS      "/proc/swaps"
++#define PATH_MKSWAP   "/sbin/mkswap"
+ #define SWAPON_NEEDS_TWO_ARGS
+@@ -173,6 +177,84 @@
+        return 0 ;
+ }
++/*
++ * It's better do swsuspend detection by follow routine than
++ * include huge mount_guess_fstype.o to swapon. We need only
++ * swsuspend and no the others filesystems.
++ */
++#ifdef HAVE_LIBBLKID
++static int
++swap_is_swsuspend(const char *device) {
++      const char *type = blkid_get_tag_value(blkid, "TYPE", device);
++      
++      if (type && strcmp(type, "swsuspend")==0)
++              return 0;
++      return 1;
++}
++#else
++static int
++swap_is_swsuspend(const char *device) {
++      int fd, re = 1, n = getpagesize() - 10;
++      char buf[10];
++      
++      fd = open(device, O_RDONLY);
++      if (fd < 0)
++              return -1;
++
++      if (lseek(fd, n, SEEK_SET) >= 0 &&
++          read(fd, buf, sizeof buf) == sizeof buf &&
++          (memcmp("S1SUSPEND", buf, 9)==0 ||
++                      memcmp("S2SUSPEND", buf, 9)==0))
++              re = 0;
++
++      close(fd);
++      return re;
++}
++#endif
++
++/* calls mkswap */
++static int
++swap_reinitialize(const char *device) {
++      const char *label = mount_get_volume_label_by_spec(device);
++      pid_t pid;
++      
++      switch((pid=fork())) {
++              case -1: /* fork error */
++                      fprintf(stderr, _("%s: cannot fork: %s\n"),
++                              progname, strerror(errno));
++                      return -1;
++                      
++              case 0: /* child */
++                      if (label && *label)
++                              execl(PATH_MKSWAP, PATH_MKSWAP, "-L", label, device, NULL);
++                      else
++                              execl(PATH_MKSWAP, PATH_MKSWAP, device, NULL);
++                      exit(1); /* error  */
++                      
++              default: /* parent */
++              {
++                      int status;
++                      int ret;
++
++                      do {
++                              if ((ret = waitpid(pid, &status, 0)) < 0 
++                                              && errno == EINTR)
++                                      continue;
++                              else if (ret < 0) {
++                                      fprintf(stderr, _("%s: waitpid: %s\n"),
++                                              progname, strerror(errno));
++                                      return -1;
++                              }
++                      } while (0);
++
++                      /* mkswap returns: 0=suss, 1=error */
++                      if (WIFEXITED(status) && WEXITSTATUS(status)==0)
++                              return 0; /* ok */
++              }
++      }
++      return -1; /* error */
++}
++      
+ static int
+ do_swapon(const char *orig_special, int prio) {
+       int status;
+@@ -196,6 +278,18 @@
+               return -1;
+       }
++      /* We have to reinitialize swap with old (=useless) software suspend 
++       * data. The problem is that if we don't do it, then we get data 
++       * corruption the next time with suspended on.
++       */
++      if (swap_is_swsuspend(special)==0) {
++              fprintf(stdout, _("%s: %s: software suspend data detected. "
++                                      "Reinitializing the swap.\n"), 
++                      progname, special);
++              if (swap_reinitialize(special) < 0)
++                      return -1;
++      }
++      
+       /* people generally dislike this warning - now it is printed
+          only when `verbose' is set */
+       if (verbose) {
+--- util-linux-2.13-pre2/mount/get_label_uuid.c.swsuspend      2005-09-02 14:32:53.000000000 +0200
++++ util-linux-2.13-pre2/mount/get_label_uuid.c        2005-09-02 16:21:20.000000000 +0200
+@@ -129,7 +129,24 @@
+       }
+       return 0;
+ }
+-          
++
++static int
++is_swsuspend_partition(int fd, char **label, char *uuid) {
++      int n = getpagesize();
++      char *buf = xmalloc(n);
++      struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf;
++
++      if (lseek(fd, 0, SEEK_SET) == 0
++          && read(fd, buf, n) == n
++          && (strncmp(buf+n-10, "S1SUSPEND", 9)==0 || 
++                  strncmp(buf+n-10, "S2SUSPEND", 9)==0)
++          && p->version == 1) {
++              store_uuid(uuid, p->uuid);
++              store_label(label, p->volume_name, 16);
++              return 1;
++      }
++      return 0;
++}
+ /*
+  * Get both label and uuid.
+@@ -162,6 +179,8 @@
+       if (is_v1_swap_partition(fd, label, uuid))
+               goto done;
++      if (is_swsuspend_partition(fd, label, uuid))
++              goto done;
+       if (lseek(fd, 1024, SEEK_SET) == 1024
+           && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb)
diff --git a/util-linux-swaponsymlink.patch b/util-linux-swaponsymlink.patch
new file mode 100644 (file)
index 0000000..b0f6115
--- /dev/null
@@ -0,0 +1,28 @@
+When swap is a simlink, the swap entry in
+/etc/fstab may not match /proc/swaps. That
+means strcmp shouldn't be used for swapon.
+
+--- util-linux-2.12p/mount/swapon.c.sopwith    Wed Dec 22 04:50:19 2004
++++ util-linux-2.12p/mount/swapon.c    Thu Dec 23 14:44:49 2004
+@@ -138,9 +138,19 @@
+ is_in_proc_swaps(const char *fname) {
+       int i;
+-      for (i = 0; i < numSwaps; i++)
+-              if (swapFiles[i] && !strcmp(fname, swapFiles[i]))
++      for (i = 0; i < numSwaps; i++) {
++              struct stat swapped, swapping;
++
++              if (!swapFiles[i]) continue;
++
++              if (!strcmp(fname, swapFiles[i])
++                  || (!stat (swapFiles[i], &swapped)
++                      && !stat (fname, &swapping)
++                      && (swapped.st_dev == swapping.st_dev
++                          && swapped.st_ino == swapping.st_ino))
++                  )
+                       return 1;
++      }
+       return 0;
+ }
diff --git a/util-linux-umount-sysfs.patch b/util-linux-umount-sysfs.patch
new file mode 100644 (file)
index 0000000..80c86fc
--- /dev/null
@@ -0,0 +1,13 @@
+- umount -a should not unmount sysfs
+
+--- util-linux-2.13-pre6/mount/umount.c.sysfs  2006-02-23 10:09:53.000000000 +0100
++++ util-linux-2.13-pre6/mount/umount.c        2006-02-23 10:10:39.000000000 +0100
+@@ -734,7 +734,7 @@
+       if (all) {
+               /* nodev stuff: sysfs, usbfs, oprofilefs, ... */
+               if (types == NULL)
+-                      types = "noproc,nodevfs,nodevpts";
++                      types = "noproc,nodevfs,nodevpts,nosysfs";
+               result = umount_all (types, test_opts);
+       } else if (argc < 1) {
+               usage (stderr, 2);
This page took 0.458463 seconds and 4 git commands to generate.