summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2013-07-07 22:10:09 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-07-07 22:10:09 +0000
commit02aba83b90e12657d14a3d416a72c49ee61ce4ab (patch)
treebfe815ae22f410f449e670585c33e3e50497ea7b /debian
parent049e0bcfa0d21cf2badc0871bbdfca3f1a7de291 (diff)
parent5a828b5de3ecb6b65adef7247679a97846d81b3d (diff)
Merge branch 'master' into HEAD
Conflicts: debian/changelog
Diffstat (limited to 'debian')
-rw-r--r--debian/changelog8
-rw-r--r--debian/patches/mount-f.patch88
-rw-r--r--debian/patches/mount-ignore-mounted-all.patch32
-rw-r--r--debian/patches/mount-loop.patch20
-rw-r--r--debian/patches/mount-n.patch37
-rw-r--r--debian/patches/mount-remount.patch67
-rw-r--r--debian/patches/mount-t-auto.patch86
-rw-r--r--debian/patches/mount-test-opts.patch214
-rw-r--r--debian/patches/procfs-default.patch48
-rw-r--r--debian/patches/procfs-get-options.patch73
-rw-r--r--debian/patches/procfs-update.patch131
-rw-r--r--debian/patches/series15
-rw-r--r--debian/patches/sutils-multiple-none.patch40
-rw-r--r--debian/patches/sutils-types.patch150
-rw-r--r--debian/patches/umount.patch382
15 files changed, 1391 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 40c0b7fa..a6c356dc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,14 @@ hurd (20130707-1) UNRELEASED; urgency=low
* New upstream snapshot (Closes: Bug#714733).
+ * patches/{mount-{f,n,remount,test-opts,ignore-mounted-all,t-auto},
+ sutils-{types,multiple-none}}.patch: New
+ patches from Justus Winter to make mount more compatible with Linux'.
+ * patches/mount-loop.patch: New patch to ignore loop option.
+ * patches/umount.patch: New patch to add umount tool.
+ * patches/procfs-{update,default,get-options}.patch: New patches from Justus
+ Winter to make procfs behave as sysvinit desires.
+
-- Samuel Thibault <sthibault@debian.org> Sun, 07 Jul 2013 22:08:24 +0000
hurd (20130620-1) unstable; urgency=low
diff --git a/debian/patches/mount-f.patch b/debian/patches/mount-f.patch
new file mode 100644
index 00000000..aabc47b7
--- /dev/null
+++ b/debian/patches/mount-f.patch
@@ -0,0 +1,88 @@
+Add -f and --fake arguments. This makes our mount more compatible with
+Linux mount.
+
+* utils/mount.c (argp_opts): Add -f and --fake.
+(do_mount): Fake the translator startup if --fake is given.
+---
+ utils/mount.c | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/utils/mount.c b/utils/mount.c
+index f1d5750..f8928f1 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -24,6 +24,7 @@
+ #include <error.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
++#include <unistd.h>
+ #include <hurd/fsys.h>
+ #include <hurd/fshelp.h>
+ #include <hurd/paths.h>
+@@ -34,6 +35,7 @@
+ static char *fstype = DEFAULT_FSTYPE;
+ static char *device, *mountpoint;
+ static int verbose;
++static int fake;
+ static char *options;
+ static size_t options_len;
+ static mach_msg_timeout_t timeout;
+@@ -55,6 +57,7 @@ static const struct argp_option argp_opts[] =
+ {"remount", 0, 0, OPTION_ALIAS},
+ {"verbose", 'v', 0, 0, "Give more detailed information"},
+ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
++ {"fake", 'f', 0, 0, "Do not actually mount, just pretend"},
+ {0, 0}
+ };
+
+@@ -115,6 +118,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
+ /* do nothing */
+ break;
+
++ case 'f':
++ fake = 1;
++ break;
++
+ case ARGP_KEY_ARG:
+ if (mountpoint == 0) /* One arg: mountpoint */
+ mountpoint = arg;
+@@ -312,7 +319,10 @@ do_mount (struct fs *fs, int remount)
+ return 0;
+ }
+
+- if (mounted != MACH_PORT_NULL)
++ /* Do not fail if there is an active translator if --fake is
++ given. This mimics Linux mount utility more closely which
++ just looks into the mtab file. */
++ if (mounted != MACH_PORT_NULL && !fake)
+ {
+ error (0, 0, "%s already mounted", fs->mntent.mnt_fsname);
+ return EBUSY;
+@@ -342,6 +352,23 @@ do_mount (struct fs *fs, int remount)
+
+ /* Now we have a translator command line argz in FSOPTS. */
+
++ if (fake) {
++ /* Fake the translator startup. */
++ mach_port_t underlying;
++ mach_msg_type_name_t underlying_type;
++ err = open_node (O_READ, &underlying, &underlying_type, 0, NULL);
++ if (err)
++ error (1, errno, "cannot mount on %s", fs->mntent.mnt_dir);
++
++ mach_port_deallocate (mach_task_self (), underlying);
++
++ /* See if the translator is at least executable. */
++ if (access(type->program, X_OK) == -1)
++ error (1, errno, "can not execute %s", type->program);
++
++ return 0;
++ }
++
+ explain ("settrans -a");
+ err = fshelp_start_translator (open_node, NULL, fsopts,
+ fsopts, fsopts_len, timeout,
+--
+1.7.10.4
+
+
diff --git a/debian/patches/mount-ignore-mounted-all.patch b/debian/patches/mount-ignore-mounted-all.patch
new file mode 100644
index 00000000..b3890d4a
--- /dev/null
+++ b/debian/patches/mount-ignore-mounted-all.patch
@@ -0,0 +1,32 @@
+Linux' mount utility ignores mounted filesystems if mount --all is
+invoked. This patch makes our mount do the same.
+
+utils/mount.c (main): Ignore mounted filesystems if --all is given.
+---
+ utils/mount.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/utils/mount.c b/utils/mount.c
+index 73a7539..77b2138 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -631,6 +631,15 @@ main (int argc, char **argv)
+
+ if (! match_options (&fs->mntent))
+ continue;
++
++ fsys_t mounted;
++ err = fs_fsys (fs, &mounted);
++ if (err)
++ error (0, err, "cannot determine if %s is already mounted",
++ fs->mntent.mnt_fsname);
++
++ if (mounted != MACH_PORT_NULL)
++ continue;
+ }
+ err |= do_mount (fs, remount);
+ }
+--
+1.7.10.4
+
+
diff --git a/debian/patches/mount-loop.patch b/debian/patches/mount-loop.patch
new file mode 100644
index 00000000..07f572be
--- /dev/null
+++ b/debian/patches/mount-loop.patch
@@ -0,0 +1,20 @@
+mount: Ignore `loop' option
+
+* utils/mount.c (do_mount): Ignore `loop' option.
+---
+ mount.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+diff --git a/utils/mount.c b/utils/mount.c
+index 8b059c2..8af055e 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -248,7 +248,8 @@ do_mount (struct fs *fs, int remount)
+ {
+ ARGZ (add (&fsopts, &fsopts_len, o));
+ }
+- else if (strcmp (o, "defaults") != 0)
++ else if (strcmp (o, "defaults") != 0 &&
++ strcmp (o, "loop") != 0)
+ {
+ /* Prepend `--' to the option to make a long option switch,
+ e.g. `--ro' or `--rsize=1024'. */
diff --git a/debian/patches/mount-n.patch b/debian/patches/mount-n.patch
new file mode 100644
index 00000000..9b860877
--- /dev/null
+++ b/debian/patches/mount-n.patch
@@ -0,0 +1,37 @@
+Add -n and --no-mtab arguments. As we do not write an mtab file, this
+is a trivial patch that just ignores this argument to be more
+compatible with Linux mount.
+
+* utils/mount.c (argp_opts): Add -n and --no-mtab.
+(parse_opt): Do nothing on 'n'.
+---
+ utils/mount.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/utils/mount.c b/utils/mount.c
+index 8b059c2..ea30f7a 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -54,6 +54,7 @@ static const struct argp_option argp_opts[] =
+ {"update", 'u', 0, 0, "Flush any meta-data cached in core"},
+ {"remount", 0, 0, OPTION_ALIAS},
+ {"verbose", 'v', 0, 0, "Give more detailed information"},
++ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
+ {0, 0}
+ };
+
+@@ -110,6 +111,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
+ }
+ break;
+
++ case 'n':
++ /* do nothing */
++ break;
++
+ case ARGP_KEY_ARG:
+ if (mountpoint == 0) /* One arg: mountpoint */
+ mountpoint = arg;
+--
+1.7.10.4
+
+
diff --git a/debian/patches/mount-remount.patch b/debian/patches/mount-remount.patch
new file mode 100644
index 00000000..53eccb2b
--- /dev/null
+++ b/debian/patches/mount-remount.patch
@@ -0,0 +1,67 @@
+This fixes mount -oremount when just given the mountpoint, e. g.:
+
+ % mount -oremount,ro /tmp
+
+* util/mount.c (main): Add a one-argument form for remount.
+---
+ utils/mount.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/utils/mount.c b/utils/mount.c
+index ea30f7a..f1d5750 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -526,6 +526,12 @@ main (int argc, char **argv)
+
+ fstab = fstab_argp_create (&fstab_params, SEARCH_FMTS, sizeof SEARCH_FMTS);
+
++ /* This is a convenient way of checking for any `remount' options. */
++ remount = 0;
++ err = argz_replace (&options, &options_len, "remount", "update", &remount);
++ if (err)
++ error (3, ENOMEM, "collecting mount options");
++
+ if (device) /* two-argument form */
+ {
+ struct mntent m =
+@@ -548,6 +554,23 @@ main (int argc, char **argv)
+ if (err)
+ error (2, err, "%s", mountpoint);
+ }
++ else if (mountpoint && remount) /* one-argument remount */
++ {
++ struct mntent m =
++ {
++ mnt_fsname: mountpoint, /* since we cannot know the device,
++ using mountpoint here leads to more
++ helpful error messages */
++ mnt_dir: mountpoint,
++ mnt_type: fstype,
++ mnt_opts: 0,
++ mnt_freq: 0, mnt_passno: 0
++ };
++
++ err = fstab_add_mntent (fstab, &m, &fs);
++ if (err)
++ error (2, err, "%s", mountpoint);
++ }
+ else if (mountpoint) /* one-argument form */
+ {
+ fs = fstab_find (fstab, mountpoint);
+@@ -557,12 +580,6 @@ main (int argc, char **argv)
+ else
+ fs = 0;
+
+- /* This is a convenient way of checking for any `remount' options. */
+- remount = 0;
+- err = argz_replace (&options, &options_len, "remount", "update", &remount);
+- if (err)
+- error (3, ENOMEM, "collecting mount options");
+-
+ if (fs != 0)
+ err = do_mount (fs, remount);
+ else
+--
+1.7.10.4
+
+
diff --git a/debian/patches/mount-t-auto.patch b/debian/patches/mount-t-auto.patch
new file mode 100644
index 00000000..5f800f41
--- /dev/null
+++ b/debian/patches/mount-t-auto.patch
@@ -0,0 +1,86 @@
+Use libblkid to detect the filesystem type if "auto" is given as
+type. Remove the translator localization from main, this is also done
+in do_mount and any errors are propagated properly. This way "auto" is
+handled correctly if given on the command line or used as filesystem
+type in the fstab.
+
+* utils/mount.c (DEFAULT_FSTYPE): Use "auto" as default type.
+(do_mount): Detect type using libblkid.
+(main): Drop translator localization.
+---
+ utils/Makefile | 1 +
+ utils/mount.c | 27 +++++++++++++++++++--------
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/utils/Makefile b/utils/Makefile
+index 6975fb5..207c904 100644
+--- a/utils/Makefile
++++ b/utils/Makefile
+@@ -37,6 +37,7 @@ LDLIBS += -lpthread
+ login-LDLIBS = -lutil $(LIBCRYPT)
+ addauth-LDLIBS = $(LIBCRYPT)
+ setauth-LDLIBS = $(LIBCRYPT)
++mount-LDLIBS = -lblkid
+
+ INSTALL-login-ops = -o root -m 4755
+ INSTALL-ids-ops = -o root -m 4755
+diff --git a/utils/mount.c b/utils/mount.c
+index 77b2138..5863f96 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -28,11 +28,12 @@
+ #include <hurd/fsys.h>
+ #include <hurd/fshelp.h>
+ #include <hurd/paths.h>
++#include <blkid/blkid.h>
+
+ #include "match-options.h"
+
+ #define SEARCH_FMTS _HURD "%sfs\0" _HURD "%s"
+-#define DEFAULT_FSTYPE "ext2"
++#define DEFAULT_FSTYPE "auto"
+
+ static char *fstype = DEFAULT_FSTYPE;
+ static char *device, *mountpoint;
+@@ -338,6 +339,23 @@ do_mount (struct fs *fs, int remount)
+ return EBUSY;
+ }
+
++ if (strcmp (fs->mntent.mnt_type, "auto") == 0)
++ {
++ char *type =
++ blkid_get_tag_value (NULL, "TYPE", fs->mntent.mnt_fsname);
++ if (! type)
++ {
++ error (0, 0, "failed to detect file system type");
++ return EFTYPE;
++ }
++ else
++ {
++ fs->mntent.mnt_type = strdup (type);
++ if (! fs->mntent.mnt_type)
++ error (3, ENOMEM, "failed to allocate memory");
++ }
++ }
++
+ err = fs_type (fs, &type);
+ if (err)
+ {
+@@ -579,13 +597,6 @@ main (int argc, char **argv)
+ mnt_opts: 0,
+ mnt_freq: 0, mnt_passno: 0
+ };
+- struct fstype *fst;
+-
+- err = fstypes_get (fstab->types, fstype, &fst);
+- if (err)
+- error (106, err, "cannot initialize type %s", fstype);
+- if (fst->program == 0)
+- error (2, 0, "filesystem type %s not recognized", fstype);
+
+ err = fstab_add_mntent (fstab, &m, &fs);
+ if (err)
+--
+1.7.10.4
+
+
diff --git a/debian/patches/mount-test-opts.patch b/debian/patches/mount-test-opts.patch
new file mode 100644
index 00000000..e694b69f
--- /dev/null
+++ b/debian/patches/mount-test-opts.patch
@@ -0,0 +1,214 @@
+--test-opts in combination with --all mounts only those filesystems
+with options matching the given set of options.
+
+Note that the semantic of the inverting "no" prefix differs from
+--types: While --types=nonfs,ufs means neither nfs nor ufs,
+--test-opts=nofoo,bar means not foo, but bar.
+
+* utils/match-options.h: New file.
+* utils/match-options.c: Likewise.
+(test_opts): New variable.
+(test_opts_len): Likewise.
+(match_options): New function.
+* utils/mount.c (parse_opt): Handle -O, --test-opts.
+(main): Use match_options as filter.
+---
+ utils/Makefile | 5 ++--
+ utils/match-options.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
+ utils/match-options.h | 33 ++++++++++++++++++++++++
+ utils/mount.c | 19 ++++++++++++--
+ 4 files changed, 121 insertions(+), 4 deletions(-)
+ create mode 100644 utils/match-options.c
+ create mode 100644 utils/match-options.h
+
+diff --git a/utils/Makefile b/utils/Makefile
+index e3bed0b..6975fb5 100644
+--- a/utils/Makefile
++++ b/utils/Makefile
+@@ -28,7 +28,8 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
+ uptime.sh psout.c ids.c vmstat.c portinfo.c devprobe.c vminfo.c \
+ parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \
+ unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \
+- rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh
++ rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
++ match-options.c
+
+ OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
+ HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
+@@ -72,7 +73,7 @@ fakeauth-CPPFLAGS = -I$(srcdir)/../auth
+ authServer-CPPFLAGS = -I$(srcdir)/../auth
+ auth_requestUser-CPPFLAGS = -I$(srcdir)/../auth
+
+-mount: ../sutils/fstab.o ../sutils/clookup.o \
++mount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
+ $(foreach L,fshelp ports,../lib$L/lib$L.a)
+ ../sutils/fstab.o ../sutils/clookup.o: FORCE
+ $(MAKE) -C $(@D) $(@F)
+diff --git a/utils/match-options.c b/utils/match-options.c
+new file mode 100644
+index 0000000..11fc9dc
+--- /dev/null
++++ b/utils/match-options.c
+@@ -0,0 +1,68 @@
++/* Common functionality for the --test-opts flag of mount and umount.
++
++ Copyright (C) 2013 Free Software Foundation, Inc.
++ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd 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, or (at
++ your option) any later version.
++
++ The GNU Hurd 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
++
++#include <argz.h>
++#include <error.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "match-options.h"
++
++char *test_opts;
++size_t test_opts_len;
++
++int
++match_options (struct mntent *mntent)
++{
++ char *opts;
++ size_t opts_len;
++
++ error_t err = argz_create_sep (mntent->mnt_opts, ',', &opts, &opts_len);
++ if (err)
++ error (3, err, "parsing mount options failed");
++
++ for (char *test = test_opts;
++ test; test = argz_next (test_opts, test_opts_len, test))
++ {
++ char *needle = test;
++ int inverse = strncmp("no", needle, 2) == 0;
++ if (inverse)
++ needle += 2;
++
++ int match = 0;
++ for (char *opt = opts; opt; opt = argz_next (opts, opts_len, opt))
++ {
++ if (strcmp (opt, needle) == 0) {
++ if (inverse)
++ return 0; /* foo in opts, nofoo in test_opts. */
++
++ /* foo in opts, foo in test_opts, record match. */
++ match = 1;
++ }
++ }
++
++ if (! inverse && ! match)
++ return 0; /* No foo in opts, but foo in test_opts. */
++ }
++
++ /* If no conflicting test_opt was encountered, return success. */
++ return 1;
++}
+diff --git a/utils/match-options.h b/utils/match-options.h
+new file mode 100644
+index 0000000..ea7ae70
+--- /dev/null
++++ b/utils/match-options.h
+@@ -0,0 +1,33 @@
++/* Common functionality for the --test-opts flag of mount and umount.
++
++ Copyright (C) 2013 Free Software Foundation, Inc.
++ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd 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, or (at
++ your option) any later version.
++
++ The GNU Hurd 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
++
++#include <mntent.h>
++
++extern char *test_opts;
++extern size_t test_opts_len;
++
++/* Check whether the given mount entry matches the given set of
++ options.
++
++ Returns 0 if foo is in the options vector but nofoo is in test_opts.
++ Returns 0 if foo is in test_opts but foo is not in the options vector. */
++int
++match_options (struct mntent *mntent);
+diff --git a/utils/mount.c b/utils/mount.c
+index f8928f1..73a7539 100644
+--- a/utils/mount.c
++++ b/utils/mount.c
+@@ -29,6 +29,8 @@
+ #include <hurd/fshelp.h>
+ #include <hurd/paths.h>
+
++#include "match-options.h"
++
+ #define SEARCH_FMTS _HURD "%sfs\0" _HURD "%s"
+ #define DEFAULT_FSTYPE "ext2"
+
+@@ -57,6 +59,8 @@ static const struct argp_option argp_opts[] =
+ {"remount", 0, 0, OPTION_ALIAS},
+ {"verbose", 'v', 0, 0, "Give more detailed information"},
+ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
++ {"test-opts", 'O', "OPTIONS", 0,
++ "Only mount fstab entries matching the given set of options"},
+ {"fake", 'f', 0, 0, "Do not actually mount, just pretend"},
+ {0, 0}
+ };
+@@ -122,6 +126,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
+ fake = 1;
+ break;
+
++ case 'O':
++ err = argz_create_sep (arg, ',', &test_opts, &test_opts_len);
++ if (err)
++ argp_failure (state, 100, ENOMEM, "%s", arg);
++ break;
++
+ case ARGP_KEY_ARG:
+ if (mountpoint == 0) /* One arg: mountpoint */
+ mountpoint = arg;
+@@ -615,8 +625,13 @@ main (int argc, char **argv)
+ case mount:
+ for (fs = fstab->entries; fs; fs = fs->next)
+ {
+- if (fstab_params.do_all && hasmntopt (&fs->mntent, MNTOPT_NOAUTO))
+- continue;
++ if (fstab_params.do_all) {
++ if (hasmntopt (&fs->mntent, MNTOPT_NOAUTO))
++ continue;
++
++ if (! match_options (&fs->mntent))
++ continue;
++ }
+ err |= do_mount (fs, remount);
+ }
+ break;
+--
+1.7.10.4
+
+
diff --git a/debian/patches/procfs-default.patch b/debian/patches/procfs-default.patch
new file mode 100644
index 00000000..62cd7b95
--- /dev/null
+++ b/debian/patches/procfs-default.patch
@@ -0,0 +1,48 @@
+Define a macro for the default value of each command line
+parameter. This allows one to generate a minimal response to
+fsys_get_options requests.
+
+* procfs/main.c: New macro definitions for default values.
+---
+ procfs/main.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/procfs/main.c b/procfs/main.c
+index ba74e87..3e53307 100644
+--- a/procfs/main.c
++++ b/procfs/main.c
+@@ -37,6 +37,13 @@ pid_t opt_fake_self;
+ pid_t opt_kernel_pid;
+ uid_t opt_anon_owner;
+
++/* Default values */
++#define OPT_CLK_TCK sysconf(_SC_CLK_TCK)
++#define OPT_STAT_MODE 0400
++#define OPT_FAKE_SELF -1
++#define OPT_KERNEL_PID 2
++#define OPT_ANON_OWNER 0
++
+ static error_t
+ argp_parser (int key, char *arg, struct argp_state *state)
+ {
+@@ -211,11 +218,11 @@ int main (int argc, char **argv)
+ mach_port_t bootstrap;
+ error_t err;
+
+- opt_clk_tck = sysconf(_SC_CLK_TCK);
+- opt_stat_mode = 0400;
+- opt_fake_self = -1;
+- opt_kernel_pid = 2;
+- opt_anon_owner = 0;
++ opt_clk_tck = OPT_CLK_TCK;
++ opt_stat_mode = OPT_STAT_MODE;
++ opt_fake_self = OPT_FAKE_SELF;
++ opt_kernel_pid = OPT_KERNEL_PID;
++ opt_anon_owner = OPT_ANON_OWNER;
+ err = argp_parse (&argp, argc, argv, 0, 0, 0);
+ if (err)
+ error (1, err, "Could not parse command line");
+--
+1.7.10.4
+
+
diff --git a/debian/patches/procfs-get-options.patch b/debian/patches/procfs-get-options.patch
new file mode 100644
index 00000000..99104177
--- /dev/null
+++ b/debian/patches/procfs-get-options.patch
@@ -0,0 +1,73 @@
+Implement our own netfs_append_args function that provides the
+appropriate command line flags if the current values differ from the
+default values.
+
+* procfs/main.c (netfs_append_args): New function.
+---
+ procfs/main.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/procfs/main.c b/procfs/main.c
+index 3e53307..bcf9590 100644
+--- a/procfs/main.c
++++ b/procfs/main.c
+@@ -22,6 +22,7 @@
+ #include <unistd.h>
+ #include <error.h>
+ #include <argp.h>
++#include <argz.h>
+ #include <hurd/netfs.h>
+ #include <ps.h>
+ #include "procfs.h"
+@@ -193,6 +194,47 @@ struct argp netfs_runtime_argp_ = {
+ /* Used by netfs_set_options to handle runtime option parsing. */
+ struct argp *netfs_runtime_argp = &netfs_runtime_argp_;
+
++/* Return an argz string describing the current options. Fill *ARGZ
++ with a pointer to newly malloced storage holding the list and *LEN
++ to the length of that storage. */
++error_t
++netfs_append_args (char **argz, size_t *argz_len)
++{
++ char buf[80];
++ error_t err = 0;
++
++#define FOPT(opt, default, fmt, args...) \
++ do { \
++ if (! err && opt != default) \
++ { \
++ snprintf (buf, sizeof buf, fmt, ## args); \
++ err = argz_add (argz, argz_len, buf); \
++ } \
++ } while (0)
++
++ FOPT (opt_clk_tck, OPT_CLK_TCK,
++ "--clk-tck=%d", opt_clk_tck);
++
++ FOPT (opt_stat_mode, OPT_STAT_MODE,
++ "--stat-mode=%o", opt_stat_mode);
++
++ FOPT (opt_fake_self, OPT_FAKE_SELF,
++ "--fake-self=%d", opt_fake_self);
++
++ FOPT (opt_anon_owner, OPT_ANON_OWNER,
++ "--anonymous-owner=%d", opt_anon_owner);
++
++ FOPT (opt_kernel_pid, OPT_KERNEL_PID,
++ "--kernel-process=%d", opt_kernel_pid);
++
++#undef FOPT
++
++ if (! err)
++ err = netfs_append_std_options (argz, argz_len);
++
++ return err;
++}
++
+ error_t
+ root_make_node (struct ps_context *pc, struct node **np)
+ {
+--
+1.7.10.4
+
+
diff --git a/debian/patches/procfs-update.patch b/debian/patches/procfs-update.patch
new file mode 100644
index 00000000..fc5cb4a7
--- /dev/null
+++ b/debian/patches/procfs-update.patch
@@ -0,0 +1,131 @@
+Split the argument handling into a common part and one for
+fsys_update_options. Handle the --update parameter; for procfs this is
+a no-op.
+
+* procfs/main.c (common_options): New variable.
+(runtime_argp_parser): Handle --update.
+(startup_argp): New variable.
+(netfs_runtime_argp_): New variable.
+---
+ procfs/main.c | 93 ++++++++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 65 insertions(+), 28 deletions(-)
+
+diff --git a/procfs/main.c b/procfs/main.c
+index 1b19c01..ba74e87 100644
+--- a/procfs/main.c
++++ b/procfs/main.c
+@@ -109,45 +109,82 @@ argp_parser (int key, char *arg, struct argp_state *state)
+ return 0;
+ }
+
++struct argp_option common_options[] = {
++ { "clk-tck", 'h', "HZ", 0,
++ "Unit used for the values expressed in system clock ticks "
++ "(default: sysconf(_SC_CLK_TCK))" },
++ { "stat-mode", 's', "MODE", 0,
++ "The [pid]/stat file publishes information which on Hurd is only "
++ "available to the process owner. "
++ "You can use this option to override its mode to be more permissive "
++ "for compatibility purposes. "
++ "(default: 0400)" },
++ { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
++ "Provide a fake \"self\" symlink to the given PID, for compatibility "
++ "purposes. If PID is omitted, \"self\" will point to init. "
++ "(default: no self link)" },
++ { "kernel-process", 'k', "PID", 0,
++ "Process identifier for the kernel, used to retreive its command "
++ "line, as well as the global up and idle times. "
++ "(default: 2)" },
++ { "compatible", 'c', NULL, 0,
++ "Try to be compatible with the Linux procps utilities. "
++ "Currently equivalent to -h 100 -s 0444 -S 1." },
++ { "anonymous-owner", 'a', "USER", 0,
++ "Make USER the owner of files related to processes without one. "
++ "Be aware that USER will be granted access to the environment and "
++ "other sensitive information about the processes in question. "
++ "(default: use uid 0)" },
++ {}
++};
++
+ struct argp argp = {
+- .options = (struct argp_option []) {
+- { "clk-tck", 'h', "HZ", 0,
+- "Unit used for the values expressed in system clock ticks "
+- "(default: sysconf(_SC_CLK_TCK))" },
+- { "stat-mode", 's', "MODE", 0,
+- "The [pid]/stat file publishes information which on Hurd is only "
+- "available to the process owner. "
+- "You can use this option to override its mode to be more permissive "
+- "for compatibility purposes. "
+- "(default: 0400)" },
+- { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
+- "Provide a fake \"self\" symlink to the given PID, for compatibility "
+- "purposes. If PID is omitted, \"self\" will point to init. "
+- "(default: no self link)" },
+- { "kernel-process", 'k', "PID", 0,
+- "Process identifier for the kernel, used to retreive its command "
+- "line, as well as the global up and idle times. "
+- "(default: 2)" },
+- { "compatible", 'c', NULL, 0,
+- "Try to be compatible with the Linux procps utilities. "
+- "Currently equivalent to -h 100 -s 0444 -S 1." },
+- { "anonymous-owner", 'a', "USER", 0,
+- "Make USER the owner of files related to processes without one. "
+- "Be aware that USER will be granted access to the environment and "
+- "other sensitive information about the processes in question. "
+- "(default: use uid 0)" },
++ .options = common_options,
++ .parser = argp_parser,
++ .doc = "A virtual filesystem emulating the Linux procfs.",
++ .children = (struct argp_child []) {
++ { &netfs_std_startup_argp, },
+ {}
+ },
++};
++
++static error_t
++runtime_argp_parser (int key, char *arg, struct argp_state *state)
++{
++ switch (key)
++ {
++ case 'u':
++ /* do nothing */
++ break;
++
++ default:
++ return ARGP_ERR_UNKNOWN;
++ }
++
++ return 0;
++}
++
++struct argp runtime_argp = {
++ .options = (struct argp_option []) {
++ { "update", 'u', NULL, 0, "remount; for procfs this does nothing" },
++ {},
++ },
++ .parser = runtime_argp_parser,
++};
++
++struct argp netfs_runtime_argp_ = {
++ .options = common_options,
+ .parser = argp_parser,
+ .doc = "A virtual filesystem emulating the Linux procfs.",
+ .children = (struct argp_child []) {
+- { &netfs_std_startup_argp, },
++ { &runtime_argp, },
++ { &netfs_std_runtime_argp, },
+ {}
+ },
+ };
+
+ /* Used by netfs_set_options to handle runtime option parsing. */
+-struct argp *netfs_runtime_argp = &argp;
++struct argp *netfs_runtime_argp = &netfs_runtime_argp_;
+
+ error_t
+ root_make_node (struct ps_context *pc, struct node **np)
+--
+1.7.10.4
+
+
diff --git a/debian/patches/series b/debian/patches/series
index 299b9452..2e80be7b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -41,3 +41,18 @@ libmachdev.patch
exec_filename_exec.patch
exec_filename_fs.patch
exec_filename_use.patch
+
+# Justus Winter's work, to be pushed
+mount-n.patch
+mount-f.patch
+mount-remount.patch
+mount-loop.patch
+procfs-update.patch
+procfs-default.patch
+procfs-get-options.patch
+sutils-types.patch
+mount-test-opts.patch
+mount-ignore-mounted-all.patch
+mount-t-auto.patch
+sutils-multiple-none.patch
+umount.patch
diff --git a/debian/patches/sutils-multiple-none.patch b/debian/patches/sutils-multiple-none.patch
new file mode 100644
index 00000000..c787b5a7
--- /dev/null
+++ b/debian/patches/sutils-multiple-none.patch
@@ -0,0 +1,40 @@
+Previously it was not possible to add two mount entries with the same
+device information to an fstab structure. This is easily fixed by
+breaking the assumption, that there is only one possible mount entry
+for the "none" device as used by many purely virtual file systems.
+
+* utils/fstab.c (fstab_find_device): Return NULL if name is "none".
+---
+ sutils/fstab.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/sutils/fstab.c b/sutils/fstab.c
+index e241de6..d3b8b6f 100644
+--- a/sutils/fstab.c
++++ b/sutils/fstab.c
+@@ -457,11 +457,19 @@ fs_remount (struct fs *fs)
+ return err;
+ }
+
+-/* Returns the FS entry in FSTAB with the device field NAME (there can only
+- be one such entry). */
++/* Returns the FS entry in FSTAB with the device field NAME.
++
++ In general there can only be one such entry. This holds not true
++ for virtual file systems that use "none" as device name.
++
++ If name is "none", NULL is returned. This also makes it possible to
++ add more than one entry for the device "none". */
+ inline struct fs *
+ fstab_find_device (const struct fstab *fstab, const char *name)
+ {
++ if (strcmp (name, "none") == 0)
++ return NULL;
++
+ struct fs *fs;
+ for (fs = fstab->entries; fs; fs = fs->next)
+ if (strcmp (fs->mntent.mnt_fsname, name) == 0)
+--
+1.7.10.4
+
+
diff --git a/debian/patches/sutils-types.patch b/debian/patches/sutils-types.patch
new file mode 100644
index 00000000..d2a21e94
--- /dev/null
+++ b/debian/patches/sutils-types.patch
@@ -0,0 +1,150 @@
+The mount utility on both Linux and FreeBSD allows one to either
+specify a whitelist or a blacklist of filesystem types to consider for
+--all. Prefixing the list with "no" indicates that the list is a
+blacklist. Furthermore, Linux' mount utility ignores a "no" prefix on
+any entry in the given list.
+
+Previously the Hurd variant first applied whitelist containing all
+positive values given and then filtered the resulting list using all
+negative values. But this makes little sense because each entry only
+has one value for the filesystem type (mnt_type) and all values are
+mutually exclusive.
+
+This patch adjusts the fstab handling code so that our mount utility
+behaves like the Linux mount utility. This code is used by both mount
+and fsck. The same argumentation applies to fsck as well.
+
+Like implemented in Linux mount, any "no" prefix is ignored to retain
+compatibility with the old behavior.
+
+* sutils/fstab.c (fstab_argp_create): Fix semantic of --types.
+---
+ sutils/fstab.c | 103 +++++++++++++++-----------------------------------------
+ 1 file changed, 27 insertions(+), 76 deletions(-)
+
+diff --git a/sutils/fstab.c b/sutils/fstab.c
+index b66e519..e241de6 100644
+--- a/sutils/fstab.c
++++ b/sutils/fstab.c
+@@ -880,90 +880,41 @@ fstab_argp_create (struct fstab_argp_params *params,
+ check = fstab;
+ else
+ {
+- struct fs *fs;
+- const char *tn;
+- unsigned int nonexclude_types;
+-
+ err = fstab_create (types, &check);
+ if (err)
+ error (105, err, "fstab_create");
+
+- /* For each excluded type (i.e. `-t notype'), clobber the
+- fstype entry's program with an empty string to mark it. */
+- nonexclude_types = 0;
+- for (tn = params->types; tn;
+- tn = argz_next (params->types, params->types_len, tn))
+- {
+- if (!strncasecmp (tn, "no", 2))
+- {
+- struct fstype *type;
+- err = fstypes_get (types, &tn[2], &type);
+- if (err)
+- error (106, err, "fstypes_get");
+- free (type->program);
+- type->program = strdup ("");
+- }
+- else
+- ++nonexclude_types;
+- }
+-
+- if (nonexclude_types != 0)
+- {
+- const char *tn;
+- struct fstypes *wanttypes;
+-
+- /* We will copy the types we want to include into a fresh
+- list in WANTTYPES. Since we specify no search formats,
+- `fstypes_get' applied to WANTTYPES can only create
+- elements with a null `program' field. */
+- err = fstypes_create (0, 0, &wanttypes);
+- if (err)
+- error (102, err, "fstypes_create");
+-
+- for (tn = params->types; tn;
+- tn = argz_next (params->types, params->types_len, tn))
+- if (strncasecmp (tn, "no", 2))
+- {
+- struct fstype *type;
+- err = fstypes_get (types, tn, &type);
+- if (err)
+- error (106, err, "fstypes_get");
+- if (type->program == 0)
+- error (0, 0,
+- "requested filesystem type `%s' unknown", tn);
+- else
+- {
+- struct fstype *newtype = malloc (sizeof *newtype);
+- newtype->name = strdup (type->name);
+- newtype->program = strdup (type->program);
+- newtype->next = wanttypes->entries;
+- wanttypes->entries = newtype;
+- }
+- }
+-
+- /* fstypes_free (types); */
+- types = wanttypes;
+- }
++ int blacklist = strncasecmp (params->types, "no", 2) == 0;
++ if (blacklist)
++ params->types += 2; /* Skip no. */
+
++ struct fs *fs;
+ for (fs = fstab->entries; fs; fs = fs->next)
+ {
+- const char *ptn;
+- struct fstype *type;
+-
+- err = fs_type (fs, &type);
+- if (err || nonexclude_types)
+- {
+- err = fstypes_get (types, fs->mntent.mnt_type, &type);
+- if (err)
+- error (106, err, "fstypes_get");
+- if (params->types != 0)
+- continue;
+- }
+- if (nonexclude_types && type->program == 0)
+- continue; /* Freshly created, was not in WANTTYPES. */
+- if (type->program != 0 && type->program[0] == '\0')
+- continue; /* This type is marked as excluded. */
++ if (strcmp (fs->mntent.mnt_type, MNTTYPE_SWAP) == 0)
++ continue; /* Ignore swap entries. */
++
++ const char *tn;
++ int matched = 0;
++ for (tn = params->types; tn;
++ tn = argz_next (params->types, params->types_len, tn))
++ {
++ const char *type = fs->mntent.mnt_type;
++ if (strcmp (type, tn) == 0
++ /* Skip no for compatibility. */
++ || ((strncasecmp (type, "no", 2) == 0)
++ && strcmp (type, tn) == 0))
++ {
++ matched = 1;
++ break;
++ }
++ }
++
++ if (matched == blacklist)
++ continue; /* Either matched and types is a blacklist
++ or not matched and types is a whitelist */
+
++ const char *ptn;
+ for (ptn = params->exclude; ptn;
+ ptn = argz_next (params->exclude, params->exclude_len, ptn))
+ if (fnmatch (ptn, fs->mntent.mnt_dir, 0) == 0)
+--
+1.7.10.4
+
+
diff --git a/debian/patches/umount.patch b/debian/patches/umount.patch
new file mode 100644
index 00000000..b2f1cafa
--- /dev/null
+++ b/debian/patches/umount.patch
@@ -0,0 +1,382 @@
+This adds a umount utility that implements most of the functions that
+the Linux umount utility provides, especially that subset that is used
+by the Debian package initscripts.
+
+* utils/umount.c: New file.
+---
+ utils/Makefile | 10 +-
+ utils/umount.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 325 insertions(+), 4 deletions(-)
+ create mode 100644 utils/umount.c
+
+diff --git a/utils/Makefile b/utils/Makefile
+index 207c904..4fe2dc2 100644
+--- a/utils/Makefile
++++ b/utils/Makefile
+@@ -21,7 +21,9 @@ makemode := utilities
+ targets = shd ps settrans showtrans syncfs fsysopts \
+ storeinfo login w uptime ids loginpr sush vmstat portinfo \
+ devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \
+- storeread msgport rpctrace mount gcore fakeauth fakeroot remap
++ storeread msgport rpctrace mount gcore fakeauth fakeroot remap \
++ umount
++
+ special-targets = loginpr sush uptime fakeroot remap
+ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
+ fsysopts.c storeinfo.c login.c loginpr.sh sush.sh w.c \
+@@ -29,7 +31,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \
+ parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \
+ unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \
+ rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \
+- match-options.c
++ match-options.c umount.c
+
+ OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
+ HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
+@@ -58,7 +60,7 @@ ftpcp ftpdir: ../libftpconn/libftpconn.a
+ settrans: ../libfshelp/libfshelp.a ../libports/libports.a
+ ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \
+ devprobe vminfo addauth rmauth setauth unsu ftpcp ftpdir storeread \
+- storecat msgport mount: \
++ storecat msgport mount umount: \
+ ../libshouldbeinlibc/libshouldbeinlibc.a
+
+ $(filter-out $(special-targets), $(targets)): %: %.o
+@@ -74,7 +76,7 @@ fakeauth-CPPFLAGS = -I$(srcdir)/../auth
+ authServer-CPPFLAGS = -I$(srcdir)/../auth
+ auth_requestUser-CPPFLAGS = -I$(srcdir)/../auth
+
+-mount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
++mount umount: ../sutils/fstab.o ../sutils/clookup.o match-options.o \
+ $(foreach L,fshelp ports,../lib$L/lib$L.a)
+ ../sutils/fstab.o ../sutils/clookup.o: FORCE
+ $(MAKE) -C $(@D) $(@F)
+diff --git a/utils/umount.c b/utils/umount.c
+new file mode 100644
+index 0000000..64e6ee2
+--- /dev/null
++++ b/utils/umount.c
+@@ -0,0 +1,319 @@
++/* Roughly Unix/Linux-compatible `umount' frontend for Hurd translators.
++
++ Copyright (C) 2013 Free Software Foundation, Inc.
++ Written by Justus Winter <4winter@informatik.uni-hamburg.de>
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd 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, or (at
++ your option) any later version.
++
++ The GNU Hurd 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
++
++#include "../sutils/fstab.h"
++#include <argp.h>
++#include <argz.h>
++#include <blkid/blkid.h>
++#include <error.h>
++#include <fcntl.h>
++#include <hurd/fshelp.h>
++#include <hurd/fsys.h>
++#include <hurd/paths.h>
++#include <hurd/process.h>
++#include <stdlib.h>
++#include <unistd.h>
++
++#include "match-options.h"
++
++/* XXX fix libc */
++#undef _PATH_MOUNTED
++#define _PATH_MOUNTED "/etc/mtab"
++
++static char *targets;
++static size_t targets_len;
++static int readonly;
++static int verbose;
++static int passive_flags = FS_TRANS_SET;
++static int active_flags = FS_TRANS_SET;
++static int goaway_flags;
++static int fake;
++
++static struct fstab_argp_params fstab_params;
++
++#define FAKE_KEY 0x80 /* !isascii (FAKE_KEY), so no short option. */
++
++static const struct argp_option argp_opts[] =
++{
++ {"fake", FAKE_KEY, 0, 0, "Do not actually umount, just pretend"},
++ {"force", 'f', 0, 0, "Force umount by killing the translator"},
++ {"no-mtab", 'n', 0, 0, "Do not update /etc/mtab"},
++ {"read-only", 'r', 0, 0, "If unmounting fails, try to remount read-only"},
++ {"nosync", 'S', 0, 0, "Don't sync a translator before killing it"},
++ {"test-opts", 'O', "OPTIONS", 0,
++ "Only mount fstab entries matching the given set of options"},
++ {"verbose", 'v', 0, 0, "Give more detailed information"},
++ {},
++};
++
++static error_t
++parse_opt (int key, char *arg, struct argp_state *state)
++{
++ struct fstab_argp_params *params = state->input;
++ error_t err;
++ switch (key)
++ {
++ case ARGP_KEY_INIT:
++ state->child_inputs[0] = params; /* pass down to fstab_argp parser */
++ break;
++
++ case FAKE_KEY:
++ fake = 1;
++ break;
++
++ case 'f':
++ goaway_flags |= FSYS_GOAWAY_FORCE;
++ break;
++
++ case 'n':
++ /* do nothing */
++ break;
++
++ case 'r':
++ readonly = 1;
++ break;
++
++ case 'S':
++ goaway_flags |= FSYS_GOAWAY_NOSYNC;
++ break;
++
++ case 'O':
++ err = argz_create_sep (arg, ',', &test_opts, &test_opts_len);
++ if (err)
++ argp_failure (state, 100, ENOMEM, "%s", arg);
++ break;
++
++ case 'v':
++ verbose += 1;
++ break;
++
++ case ARGP_KEY_ARG:
++ err = argz_add (&targets, &targets_len, arg);
++ if (err)
++ argp_failure (state, 100, ENOMEM, "%s", arg);
++ break;
++
++ case ARGP_KEY_NO_ARGS:
++ if (! params->do_all)
++ {
++ argp_error (state,
++ "filesystem argument required if --all is not given");
++ return EINVAL;
++ }
++ break;
++
++ case ARGP_KEY_END:
++ if (params->do_all && targets)
++ {
++ argp_error (state, "filesystem argument not allowed with --all");
++ return EINVAL;
++ }
++ break;
++
++ default:
++ return ARGP_ERR_UNKNOWN;
++ }
++
++ return 0;
++}
++
++static const char doc[] = "Stop active and remove passive translators";
++static const char args_doc[] = "DEVICE|DIRECTORY [DEVICE|DIRECTORY ...]";
++
++static struct argp fstab_argp_mtab; /* Slightly modified version. */
++
++static const struct argp_child argp_kids[] =
++{
++ {&fstab_argp_mtab, 0,
++ "Filesystem selection (if no explicit filesystem arguments given):", 2},
++ {},
++};
++static struct argp argp =
++{
++ options: argp_opts,
++ parser: parse_opt,
++ args_doc: args_doc,
++ doc: doc,
++ children: argp_kids,
++};
++
++/* This is a trimmed and slightly modified version of
++ fstab_argp.options which uses _PATH_MOUNTED instead of _PATH_MNTTAB
++ in the doc strings. */
++static const struct argp_option fstab_argp_mtab_opts[] =
++{
++ {"all", 'a', 0, 0, "Do all filesystems in " _PATH_MOUNTED},
++ {0, 'A', 0, OPTION_ALIAS },
++ {"fstab", 'F', "FILE", 0, "File to use instead of " _PATH_MOUNTED},
++ {"fstype", 't', "TYPE", 0, "Do only filesystems of given type(s)"},
++ {"exclude-root",'R',0, 0,
++ "Exclude root (/) filesystem from " _PATH_MOUNTED " list"},
++ {"exclude", 'X', "PATTERN", 0, "Exclude directories matching PATTERN"},
++ {}
++};
++
++static error_t
++fstab_argp_mtab_parse_opt (int key, char *arg, struct argp_state *state)
++{
++ return fstab_argp.parser (key, arg, state);
++}
++
++static struct argp fstab_argp_mtab =
++{
++ options: fstab_argp_mtab_opts,
++ parser: fstab_argp_mtab_parse_opt,
++};
++
++/* Unmount one filesystem. */
++static error_t
++do_umount (struct fs *fs)
++{
++ error_t err = 0;
++
++ file_t node = file_name_lookup(fs->mntent.mnt_dir, O_NOTRANS, 0666);
++ if (node == MACH_PORT_NULL)
++ {
++ error(0, errno, "%s", fs->mntent.mnt_dir);
++ return errno;
++ }
++
++ if (verbose)
++ printf ("settrans -pg%s%s %s\n",
++ goaway_flags & FSYS_GOAWAY_NOSYNC? "S": "",
++ goaway_flags & FSYS_GOAWAY_FORCE? "f": "",
++ fs->mntent.mnt_dir);
++
++ if (! fake)
++ {
++ err = file_set_translator (node,
++ passive_flags, active_flags, goaway_flags,
++ NULL, 0,
++ MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
++ if (err)
++ {
++ error (0, err, "%s", fs->mntent.mnt_dir);
++
++ /* Try remounting readonly instead if requested. */
++ if (readonly)
++ {
++ if (verbose)
++ printf ("fsysopts %s --readonly\n", fs->mntent.mnt_dir);
++
++ error_t e = fs_set_readonly (fs, TRUE);
++ if (e)
++ error (0, e, "%s", fs->mntent.mnt_dir);
++ }
++ }
++ }
++
++ /* Deallocate the reference so that unmounting nested translators
++ works properly. */
++ mach_port_deallocate (mach_task_self (), node);
++ return err;
++}
++
++int
++main (int argc, char **argv)
++{
++ error_t err;
++
++ err = argp_parse (&argp, argc, argv, 0, 0, &fstab_params);
++ if (err)
++ error (3, err, "parsing arguments");
++
++ /* Read the mtab file by default. */
++ if (! fstab_params.fstab_path)
++ fstab_params.fstab_path = _PATH_MOUNTED;
++
++ struct fstab *fstab = fstab_argp_create (&fstab_params, NULL, 0);
++ if (! fstab)
++ error (3, ENOMEM, "fstab creation");
++
++ if (targets)
++ for (char *t = targets; t; t = argz_next (targets, targets_len, t))
++ {
++ /* Figure out if t is the device or the mountpoint. */
++ struct fs *fs = fstab_find_mount (fstab, t);
++ if (! fs)
++ {
++ fs = fstab_find_device (fstab, t);
++ if (! fs)
++ {
++ error (0, 0, "could not find entry for: %s", t);
++
++ /* As last resort, just assume it is the mountpoint. */
++ struct mntent m =
++ {
++ mnt_fsname: "",
++ mnt_dir: t,
++ mnt_type: "",
++ mnt_opts: 0,
++ mnt_freq: 0,
++ mnt_passno: 0,
++ };
++
++ err = fstab_add_mntent (fstab, &m, &fs);
++ if (err)
++ error (2, err, "%s", t);
++ }
++ }
++
++ if (fs)
++ err |= do_umount (fs);
++ }
++ else
++ {
++ /* Sort entries. */
++ size_t count = 0;
++ for (struct fs *fs = fstab->entries; fs; fs = fs->next)
++ count += 1;
++
++ char **entries = malloc (count * sizeof (char *));
++ if (! entries)
++ error (3, ENOMEM, "allocating entries array");
++
++ char **p = entries;
++ for (struct fs *fs = fstab->entries; fs; fs = fs->next)
++ *p++ = fs->mntent.mnt_dir;
++
++ /* Reverse lexicographical order. */
++ int compare_entries (const void *a, const void *b)
++ {
++ return -strcmp ((char *) a, (char *) b);
++ }
++
++ qsort (entries, count, sizeof (char *), compare_entries);
++
++ for (int i = 0; i < count; i++)
++ {
++ struct fs *fs = fstab_find_mount (fstab, entries[i]);
++ if (! fs)
++ error (4, 0, "could not find entry for: %s", entries[i]);
++
++ if (! match_options (&fs->mntent))
++ continue;
++
++ err |= do_umount (fs);
++ }
++ }
++
++ return err? EXIT_FAILURE: EXIT_SUCCESS;
++}
+--
+1.7.10.4
+
+