basebuilder_pel7ppc64bebuilder0
7 years ago
64 changed files with 17036 additions and 17 deletions
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/kill.c.kzak util-linux-2.23.2/misc-utils/kill.c |
||||
--- util-linux-2.23.2/misc-utils/kill.c.kzak 2013-06-13 09:46:10.448650861 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/kill.c 2014-09-25 10:08:27.879359310 +0200 |
||||
@@ -48,6 +48,7 @@ |
||||
#include <ctype.h> /* for isdigit() */ |
||||
#include <unistd.h> |
||||
#include <signal.h> |
||||
+#include <errno.h> |
||||
|
||||
#include "c.h" |
||||
#include "nls.h" |
||||
@@ -279,8 +280,9 @@ int main (int argc, char *argv[]) |
||||
the rest of the arguments should be process ids and names. |
||||
kill them. */ |
||||
for (errors = 0; (arg = *argv) != NULL; argv++) { |
||||
+ errno = 0; |
||||
pid = strtol (arg, &ep, 10); |
||||
- if (! *ep) |
||||
+ if (errno == 0 && ep && *ep == '\0' && arg < ep) |
||||
errors += kill_verbose (arg, pid, numsig); |
||||
else { |
||||
struct proc_processes *ps = proc_open_processes(); |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
diff -up util-linux-2.23.2/login-utils/login.c.kzak util-linux-2.23.2/login-utils/login.c |
||||
--- util-linux-2.23.2/login-utils/login.c.kzak 2013-07-30 10:39:26.222738397 +0200 |
||||
+++ util-linux-2.23.2/login-utils/login.c 2013-09-09 09:01:39.923225757 +0200 |
||||
@@ -502,7 +502,7 @@ static void log_lastlog(struct login_con |
||||
if (!cxt->pwd) |
||||
return; |
||||
|
||||
- fd = open(_PATH_LASTLOG, O_RDWR, 0); |
||||
+ fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0); |
||||
if (fd < 0) |
||||
return; |
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
diff -up util-linux-2.23.2/term-utils/agetty.c.kzak util-linux-2.23.2/term-utils/agetty.c |
||||
--- util-linux-2.23.2/term-utils/agetty.c.kzak 2013-07-30 11:14:18.124912322 +0200 |
||||
+++ util-linux-2.23.2/term-utils/agetty.c 2013-09-09 09:07:46.406689270 +0200 |
||||
@@ -132,13 +132,20 @@ struct options { |
||||
int delay; /* Sleep seconds before prompt */ |
||||
int nice; /* Run login with this priority */ |
||||
int numspeed; /* number of baud rates to try */ |
||||
+ int clocal; /* CLOCAL_MODE_* */ |
||||
speed_t speeds[MAX_SPEED]; /* baud rates to be tried */ |
||||
}; |
||||
|
||||
+enum { |
||||
+ CLOCAL_MODE_AUTO = 0, |
||||
+ CLOCAL_MODE_ALWAYS, |
||||
+ CLOCAL_MODE_NEVER |
||||
+}; |
||||
+ |
||||
#define F_PARSE (1<<0) /* process modem status messages */ |
||||
#define F_ISSUE (1<<1) /* display /etc/issue */ |
||||
#define F_RTSCTS (1<<2) /* enable RTS/CTS flow control */ |
||||
-#define F_LOCAL (1<<3) /* force local */ |
||||
+ |
||||
#define F_INITSTRING (1<<4) /* initstring is set */ |
||||
#define F_WAITCRLF (1<<5) /* wait for CR or LF */ |
||||
#define F_CUSTISSUE (1<<6) /* give alternative issue file */ |
||||
@@ -235,10 +242,13 @@ static void login_options_to_argv(char * |
||||
static char *fakehost; |
||||
|
||||
#ifdef DEBUGGING |
||||
-#define debug(s) do { fprintf(dbf,s); fflush(dbf); } while (0) |
||||
+# ifndef DEBUG_OUTPUT |
||||
+# define DEBUG_OUTPUT "/dev/ttyp0" |
||||
+# endif |
||||
+# define debug(s) do { fprintf(dbf,s); fflush(dbf); } while (0) |
||||
FILE *dbf; |
||||
#else |
||||
-#define debug(s) do { ; } while (0) |
||||
+# define debug(s) do { ; } while (0) |
||||
#endif |
||||
|
||||
int main(int argc, char **argv) |
||||
@@ -270,7 +280,7 @@ int main(int argc, char **argv) |
||||
sigaction(SIGINT, &sa, &sa_int); |
||||
|
||||
#ifdef DEBUGGING |
||||
- dbf = fopen("/dev/ttyp0", "w"); |
||||
+ dbf = fopen(DEBUG_OUTPUT, "w"); |
||||
for (int i = 1; i < argc; i++) |
||||
debug(argv[i]); |
||||
#endif /* DEBUGGING */ |
||||
@@ -311,8 +321,10 @@ int main(int argc, char **argv) |
||||
strlen(options.initstring)); |
||||
} |
||||
|
||||
- if (!serial_tty_option(&options, F_LOCAL)) |
||||
- /* Go to blocking write mode unless -L is specified. */ |
||||
+ if (options.flags & F_VCONSOLE || options.clocal != CLOCAL_MODE_ALWAYS) |
||||
+ /* Go to blocking mode unless -L is specified, this change |
||||
+ * affects stdout, stdin and stderr as all the file descriptors |
||||
+ * are created by dup(). */ |
||||
fcntl(STDOUT_FILENO, F_SETFL, |
||||
fcntl(STDOUT_FILENO, F_GETFL, 0) & ~O_NONBLOCK); |
||||
|
||||
@@ -420,6 +432,12 @@ int main(int argc, char **argv) |
||||
options.tty); |
||||
} |
||||
|
||||
+#ifdef DEBUGGING |
||||
+ fprintf(dbf, "read %c\n", ch); |
||||
+ if (close_stream(dbf) != 0) |
||||
+ log_err("write failed: %s", DEBUG_OUTPUT); |
||||
+#endif |
||||
+ |
||||
/* Let the login program take care of password validation. */ |
||||
execv(options.login, login_argv); |
||||
log_err(_("%s: can't exec %s: %m"), options.tty, login_argv[0]); |
||||
@@ -534,7 +552,7 @@ static void parse_args(int argc, char ** |
||||
{ "init-string", required_argument, 0, 'I' }, |
||||
{ "noclear", no_argument, 0, 'J' }, |
||||
{ "login-program", required_argument, 0, 'l' }, |
||||
- { "local-line", no_argument, 0, 'L' }, |
||||
+ { "local-line", optional_argument, 0, 'L' }, |
||||
{ "extract-baud", no_argument, 0, 'm' }, |
||||
{ "skip-login", no_argument, 0, 'n' }, |
||||
{ "nonewline", no_argument, 0, 'N' }, |
||||
@@ -603,7 +621,18 @@ static void parse_args(int argc, char ** |
||||
op->login = optarg; |
||||
break; |
||||
case 'L': |
||||
- op->flags |= F_LOCAL; |
||||
+ /* -L and -L=always have the same meaning */ |
||||
+ op->clocal = CLOCAL_MODE_ALWAYS; |
||||
+ if (optarg) { |
||||
+ if (strcmp(optarg, "=always") == 0) |
||||
+ op->clocal = CLOCAL_MODE_ALWAYS; |
||||
+ else if (strcmp(optarg, "=never") == 0) |
||||
+ op->clocal = CLOCAL_MODE_NEVER; |
||||
+ else if (strcmp(optarg, "=auto") == 0) |
||||
+ op->clocal = CLOCAL_MODE_AUTO; |
||||
+ else |
||||
+ log_err(_("unssuported --local-line mode argument")); |
||||
+ } |
||||
break; |
||||
case 'm': |
||||
op->flags |= F_PARSE; |
||||
@@ -1090,8 +1119,19 @@ static void termio_init(struct options * |
||||
cfsetispeed(tp, ispeed); |
||||
cfsetospeed(tp, ospeed); |
||||
|
||||
- if (op->flags & F_LOCAL) |
||||
- tp->c_cflag |= CLOCAL; |
||||
+ /* The default is to follow setting from kernel, but it's possible |
||||
+ * to explicitly remove/add CLOCAL flag by -L[=<mode>]*/ |
||||
+ switch (op->clocal) { |
||||
+ case CLOCAL_MODE_ALWAYS: |
||||
+ tp->c_cflag |= CLOCAL; /* -L or -L=always */ |
||||
+ break; |
||||
+ case CLOCAL_MODE_NEVER: |
||||
+ tp->c_cflag &= ~CLOCAL; /* -L=never */ |
||||
+ break; |
||||
+ case CLOCAL_MODE_AUTO: /* -L=auto */ |
||||
+ break; |
||||
+ } |
||||
+ |
||||
#ifdef HAVE_STRUCT_TERMIOS_C_LINE |
||||
tp->c_line = 0; |
||||
#endif |
||||
@@ -1412,9 +1452,10 @@ static char *get_logname(struct options |
||||
|
||||
if (read(STDIN_FILENO, &c, 1) < 1) { |
||||
|
||||
- /* Do not report trivial like EINTR/EIO errors. */ |
||||
+ /* The terminal could be open with O_NONBLOCK when |
||||
+ * -L (force CLOCAL) is specified... */ |
||||
if (errno == EINTR || errno == EAGAIN) { |
||||
- usleep(1000); |
||||
+ usleep(250000); |
||||
continue; |
||||
} |
||||
switch (errno) { |
||||
@@ -1648,7 +1689,7 @@ static void __attribute__ ((__noreturn__ |
||||
fputs(_(" -i, --noissue do not display issue file\n"), out); |
||||
fputs(_(" -I, --init-string <string> set init string\n"), out); |
||||
fputs(_(" -l, --login-program <file> specify login program\n"), out); |
||||
- fputs(_(" -L, --local-line force local line\n"), out); |
||||
+ fputs(_(" -L, --local-line[=<mode>] cotrol local line flag\n"), out); |
||||
fputs(_(" -m, --extract-baud extract baud rate during connect\n"), out); |
||||
fputs(_(" -n, --skip-login do not prompt for login\n"), out); |
||||
fputs(_(" -o, --login-options <opts> options that are passed to login\n"), out); |
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h |
||||
--- util-linux-2.23.2/include/pathnames.h.kzak 2013-07-30 10:39:26.201738190 +0200 |
||||
+++ util-linux-2.23.2/include/pathnames.h 2013-09-12 13:05:35.928359383 +0200 |
||||
@@ -63,6 +63,7 @@ |
||||
|
||||
/* used in term-utils/agetty.c */ |
||||
#define _PATH_ISSUE "/etc/issue" |
||||
+#define _PATH_OS_RELEASE "/etc/os-release" |
||||
#define _PATH_NUMLOCK_ON _PATH_LOCALSTATEDIR "/numlock-on" |
||||
|
||||
#define _PATH_LOGINDEFS "/etc/login.defs" |
||||
diff -up util-linux-2.23.2/term-utils/agetty.8.kzak util-linux-2.23.2/term-utils/agetty.8 |
||||
--- util-linux-2.23.2/term-utils/agetty.8.kzak 2013-07-30 10:58:20.889261333 +0200 |
||||
+++ util-linux-2.23.2/term-utils/agetty.8 2013-09-12 13:05:35.928359383 +0200 |
||||
@@ -310,6 +310,14 @@ Insert the current date. |
||||
.TP |
||||
s |
||||
Insert the system name, the name of the operating system. Same as `uname \-s'. |
||||
+See also \\S escape code. |
||||
+.TP |
||||
+S or S{VARIABLE} |
||||
+Insert the VARIABLE data from \fI/etc/os-release\fP. If the VARIABLE argument |
||||
+is not specified then use PRETTY_NAME from the file or the system name (see \\s). |
||||
+This escape code allows to keep \fI/etc/issue\fP distribution and release |
||||
+independent. Note that \\S{ANSI_COLOR} is converted to the real terminal |
||||
+escape sequence. |
||||
.TP |
||||
l |
||||
Insert the name of the current tty line. |
||||
@@ -368,11 +376,14 @@ the system status file. |
||||
.B /etc/issue |
||||
printed before the login prompt. |
||||
.TP |
||||
+.B /etc/os-release |
||||
+operating system identification data. |
||||
+.TP |
||||
.B /dev/console |
||||
problem reports (if syslog(3) is not used). |
||||
.TP |
||||
.B /etc/inittab |
||||
-\fIinit\fP(8) configuration file. |
||||
+\fIinit\fP(8) configuration file for SysV-style init daemon. |
||||
.SH BUGS |
||||
.ad |
||||
.fi |
||||
diff -up util-linux-2.23.2/term-utils/agetty.c.kzak util-linux-2.23.2/term-utils/agetty.c |
||||
--- util-linux-2.23.2/term-utils/agetty.c.kzak 2013-09-12 13:05:35.927359379 +0200 |
||||
+++ util-linux-2.23.2/term-utils/agetty.c 2013-09-12 13:05:35.929359388 +0200 |
||||
@@ -129,6 +129,7 @@ struct options { |
||||
char *issue; /* alternative issue file */ |
||||
char *erasechars; /* string with erase chars */ |
||||
char *killchars; /* string with kill chars */ |
||||
+ char *osrelease; /* /etc/os-release data */ |
||||
int delay; /* Sleep seconds before prompt */ |
||||
int nice; /* Run login with this priority */ |
||||
int numspeed; /* number of baud rates to try */ |
||||
@@ -431,7 +432,8 @@ int main(int argc, char **argv) |
||||
log_warn(_("%s: can't change process priority: %m"), |
||||
options.tty); |
||||
} |
||||
- |
||||
+ if (options.osrelease) |
||||
+ free(options.osrelease); |
||||
#ifdef DEBUGGING |
||||
fprintf(dbf, "read %c\n", ch); |
||||
if (close_stream(dbf) != 0) |
||||
@@ -1279,6 +1281,84 @@ static char *xgetdomainname(void) |
||||
return NULL; |
||||
} |
||||
|
||||
+static char *read_os_release(struct options *op, const char *varname) |
||||
+{ |
||||
+ int fd = -1; |
||||
+ struct stat st; |
||||
+ size_t varsz = strlen(varname); |
||||
+ char *p, *buf = NULL, *ret = NULL; |
||||
+ |
||||
+ /* read the file only once */ |
||||
+ if (!op->osrelease) { |
||||
+ fd = open(_PATH_OS_RELEASE, O_RDONLY); |
||||
+ if (fd == -1) { |
||||
+ log_warn(_("cannot open: %s: %m"), _PATH_OS_RELEASE); |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ if (fstat(fd, &st) < 0 || st.st_size > 4 * 1024 * 1024) |
||||
+ goto done; |
||||
+ |
||||
+ op->osrelease = malloc(st.st_size + 1); |
||||
+ if (!op->osrelease) |
||||
+ log_err(_("failed to allocate memory: %m")); |
||||
+ if (read_all(fd, op->osrelease, st.st_size) != (ssize_t) st.st_size) { |
||||
+ free(op->osrelease); |
||||
+ op->osrelease = NULL; |
||||
+ goto done; |
||||
+ } |
||||
+ op->osrelease[st.st_size] = 0; |
||||
+ } |
||||
+ buf = strdup(op->osrelease); |
||||
+ if (!buf) |
||||
+ log_err(_("failed to allocate memory: %m")); |
||||
+ p = buf; |
||||
+ |
||||
+ for (;;) { |
||||
+ char *eol, *eon; |
||||
+ |
||||
+ p += strspn(p, "\n\r"); |
||||
+ p += strspn(p, " \t\n\r"); |
||||
+ if (!*p) |
||||
+ break; |
||||
+ if (strspn(p, "#;\n") != 0) { |
||||
+ p += strcspn(p, "\n\r"); |
||||
+ continue; |
||||
+ } |
||||
+ if (strncmp(p, varname, varsz) != 0) { |
||||
+ p += strcspn(p, "\n\r"); |
||||
+ continue; |
||||
+ } |
||||
+ p += varsz; |
||||
+ p += strspn(p, " \t\n\r=\""); |
||||
+ eol = p + strcspn(p, "\n\r"); |
||||
+ *eol = '\0'; |
||||
+ eon = eol-1; |
||||
+ while (eon > p) { |
||||
+ if (*eon == '\t' || *eon == ' ') { |
||||
+ eon--; |
||||
+ continue; |
||||
+ } |
||||
+ if (*eon == '"') { |
||||
+ *eon = '\0'; |
||||
+ break; |
||||
+ } |
||||
+ break; |
||||
+ } |
||||
+ if (ret) |
||||
+ free(ret); |
||||
+ ret = strdup(p); |
||||
+ if (!ret) |
||||
+ log_err(_("failed to allocate memory: %m")); |
||||
+ p = eol + 1; |
||||
+ } |
||||
+done: |
||||
+ free(buf); |
||||
+ if (fd >= 0) |
||||
+ close(fd); |
||||
+ return ret; |
||||
+} |
||||
+ |
||||
/* Show login prompt, optionally preceded by /etc/issue contents. */ |
||||
static void do_prompt(struct options *op, struct termios *tp) |
||||
{ |
||||
@@ -1968,6 +2048,24 @@ static void output_special_char(unsigned |
||||
} |
||||
break; |
||||
} |
||||
+ case 'S': |
||||
+ { |
||||
+ char *var = NULL, varname[64]; |
||||
+ |
||||
+ if (get_escape_argument(fp, varname, sizeof(varname))) |
||||
+ var = read_os_release(op, varname); |
||||
+ else if (!(var = read_os_release(op, "PRETTY_NAME"))) |
||||
+ var = uts.sysname; |
||||
+ if (var) { |
||||
+ if (strcmp(varname, "ANSI_COLOR") == 0) |
||||
+ printf("\033[%sm", var); |
||||
+ else |
||||
+ printf("%s", var); |
||||
+ if (var != uts.sysname) |
||||
+ free(var); |
||||
+ } |
||||
+ break; |
||||
+ } |
||||
case 'u': |
||||
case 'U': |
||||
{ |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From 7ab32ae64d05f018c171ba1525bc337805d84391 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Fri, 11 Oct 2013 11:16:23 +0200 |
||||
Subject: [PATCH] blockdev: add note about --setbsz usability |
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
disk-utils/blockdev.8 | 4 +++- |
||||
disk-utils/blockdev.c | 2 +- |
||||
2 files changed, 4 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/disk-utils/blockdev.8 b/disk-utils/blockdev.8 |
||||
index 2b3d64c..f4282da 100644 |
||||
--- a/disk-utils/blockdev.8 |
||||
+++ b/disk-utils/blockdev.8 |
||||
@@ -68,7 +68,9 @@ Get size in 512-byte sectors. |
||||
.IP "\fB\-\-rereadpt\fP" |
||||
Reread partition table |
||||
.IP "\fB\-\-setbsz\fP \fIbytes\fP" |
||||
-Set blocksize. |
||||
+Set blocksize. Note that the block size is specific to the current file |
||||
+descriptor opening the block device, so the change of block size only persists |
||||
+for as long as blockdev has the device open, and is lost once blockdev exits. |
||||
.IP "\fB\-\-setfra\fP \fIsectors\fP" |
||||
Set filesystem readahead (same like --setra on 2.6 kernels). |
||||
.IP "\fB\-\-setra\fP \fIsectors\fP" |
||||
diff --git a/disk-utils/blockdev.c b/disk-utils/blockdev.c |
||||
index 4543818..d030217 100644 |
||||
--- a/disk-utils/blockdev.c |
||||
+++ b/disk-utils/blockdev.c |
||||
@@ -127,7 +127,7 @@ static const struct bdc bdcms[] = |
||||
.argname = "<bytes>", |
||||
.argtype = ARG_INT, |
||||
.flags = FL_NORESULT, |
||||
- .help = N_("set blocksize") |
||||
+ .help = N_("set blocksize on file descriptor opening the block device") |
||||
},{ |
||||
IOCTL_ENTRY(BLKGETSIZE), |
||||
.name = "--getsize", |
||||
-- |
||||
1.8.3.1 |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
diff -up util-linux-2.23.2/disk-utils/fsck.c.kzak util-linux-2.23.2/disk-utils/fsck.c |
||||
--- util-linux-2.23.2/disk-utils/fsck.c.kzak 2013-06-13 09:46:10.377650254 +0200 |
||||
+++ util-linux-2.23.2/disk-utils/fsck.c 2014-03-25 12:46:59.525939425 +0100 |
||||
@@ -437,10 +437,14 @@ static void load_fs_info(void) |
||||
if (mnt_table_parse_fstab(fstab, path)) { |
||||
if (!path) |
||||
path = mnt_get_fstab_path(); |
||||
- if (errno) |
||||
- warn(_("%s: failed to parse fstab"), path); |
||||
- else |
||||
- warnx(_("%s: failed to parse fstab"), path); |
||||
+ |
||||
+ /* don't print error when there is no fstab at all */ |
||||
+ if (access(path, F_OK) == 0) { |
||||
+ if (errno) |
||||
+ warn(_("%s: failed to parse fstab"), path); |
||||
+ else |
||||
+ warnx(_("%s: failed to parse fstab"), path); |
||||
+ } |
||||
} |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
From 44baaedaffee029dca76796b933412d97a19dff6 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 9 Sep 2013 10:57:50 +0200 |
||||
Subject: [PATCH] libfdisk: fix SIGFPE |
||||
|
||||
#0 recount_geometry at libfdisk/src/alignment.c:143 |
||||
#1 fdisk_discover_geometry at libfdisk/src/alignment.c:205 |
||||
#2 fdisk_context_assign_device at libfdisk/src/context.c:173 |
||||
#3 print_partition_table_from_option at fdisks/fdisk.c:924 |
||||
|
||||
References: https://bugzilla.redhat.com/show_bug.cgi?id=1005566 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libfdisk/src/alignment.c | 9 +++++---- |
||||
1 file changed, 5 insertions(+), 4 deletions(-) |
||||
|
||||
diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c |
||||
index ac44e73..4d4ab48 100644 |
||||
--- a/libfdisk/src/alignment.c |
||||
+++ b/libfdisk/src/alignment.c |
||||
@@ -193,11 +193,12 @@ int fdisk_discover_geometry(struct fdisk_context *cxt) |
||||
|
||||
/* what the kernel/bios thinks the geometry is */ |
||||
blkdev_get_geometry(cxt->dev_fd, &h, &s); |
||||
- if (!h && !s) { |
||||
- /* unable to discover geometry, use default values */ |
||||
- s = 63; |
||||
+ |
||||
+ /* defaults */ |
||||
+ if (!h) |
||||
h = 255; |
||||
- } |
||||
+ if (!s) |
||||
+ s = 63; |
||||
|
||||
/* obtained heads and sectors */ |
||||
cxt->geom.heads = h; |
||||
-- |
||||
1.8.1.4 |
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
diff -up util-linux-2.23.2/libmount/src/tab.c.kzak util-linux-2.23.2/libmount/src/tab.c |
||||
--- util-linux-2.23.2/libmount/src/tab.c.kzak 2013-07-30 10:39:26.218738358 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/tab.c 2014-09-25 10:53:43.525269554 +0200 |
||||
@@ -47,6 +47,8 @@ |
||||
#include "strutils.h" |
||||
#include "loopdev.h" |
||||
|
||||
+static int is_mountinfo(struct libmnt_table *tb); |
||||
+ |
||||
/** |
||||
* mnt_new_table: |
||||
* |
||||
@@ -233,7 +235,7 @@ int mnt_table_get_root_fs(struct libmnt_ |
||||
assert(tb); |
||||
assert(root); |
||||
|
||||
- if (!tb || !root) |
||||
+ if (!tb || !root || !is_mountinfo(tb)) |
||||
return -EINVAL; |
||||
|
||||
DBG(TAB, mnt_debug_h(tb, "lookup root fs")); |
||||
@@ -241,8 +243,6 @@ int mnt_table_get_root_fs(struct libmnt_ |
||||
mnt_reset_iter(&itr, MNT_ITER_FORWARD); |
||||
while(mnt_table_next_fs(tb, &itr, &fs) == 0) { |
||||
int id = mnt_fs_get_parent_id(fs); |
||||
- if (!id) |
||||
- break; /* @tab is not mountinfo file? */ |
||||
|
||||
if (!*root || id < root_id) { |
||||
*root = fs; |
||||
@@ -250,7 +250,7 @@ int mnt_table_get_root_fs(struct libmnt_ |
||||
} |
||||
} |
||||
|
||||
- return root_id ? 0 : -EINVAL; |
||||
+ return *root ? 0 : -EINVAL; |
||||
} |
||||
|
||||
/** |
||||
@@ -271,15 +271,13 @@ int mnt_table_next_child_fs(struct libmn |
||||
struct libmnt_fs *fs; |
||||
int parent_id, lastchld_id = 0, chld_id = 0; |
||||
|
||||
- if (!tb || !itr || !parent) |
||||
+ if (!tb || !itr || !parent || !is_mountinfo(tb)) |
||||
return -EINVAL; |
||||
|
||||
DBG(TAB, mnt_debug_h(tb, "lookup next child of '%s'", |
||||
mnt_fs_get_target(parent))); |
||||
|
||||
parent_id = mnt_fs_get_id(parent); |
||||
- if (!parent_id) |
||||
- return -EINVAL; |
||||
|
||||
/* get ID of the previously returned child */ |
||||
if (itr->head && itr->p != itr->head) { |
||||
@@ -310,7 +308,7 @@ int mnt_table_next_child_fs(struct libmn |
||||
} |
||||
} |
||||
|
||||
- if (!chld_id) |
||||
+ if (!*chld) |
||||
return 1; /* end of iterator */ |
||||
|
||||
/* set the iterator to the @chld for the next call */ |
||||
diff -up util-linux-2.23.2/misc-utils/findmnt.c.kzak util-linux-2.23.2/misc-utils/findmnt.c |
||||
--- util-linux-2.23.2/misc-utils/findmnt.c.kzak 2013-07-30 11:07:35.138395654 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/findmnt.c 2014-09-25 10:49:50.953050560 +0200 |
||||
@@ -826,8 +826,9 @@ static int tab_is_tree(struct libmnt_tab |
||||
if (!itr) |
||||
return 0; |
||||
|
||||
- if (mnt_table_next_fs(tb, itr, &fs) == 0) |
||||
- rc = mnt_fs_get_id(fs) > 0 && mnt_fs_get_parent_id(fs) > 0; |
||||
+ rc = (mnt_table_next_fs(tb, itr, &fs) == 0 && |
||||
+ mnt_fs_is_kernel(fs) && |
||||
+ mnt_fs_get_root(fs)); |
||||
|
||||
mnt_free_iter(itr); |
||||
return rc; |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
From 3f420a49dd4d0c413b635dd621aa34eebce2d3d2 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 5 Aug 2013 13:58:01 +0200 |
||||
Subject: [PATCH] libmount: canonicalize for conversion from loopdev backing |
||||
file |
||||
|
||||
# mount foo.img /mnt |
||||
# umount foo.img |
||||
umount: foo.img: not mounted |
||||
|
||||
The loopdev code (and sysfs backing_file) uses absolute paths, but |
||||
libmount does not canonicalize the path before lookup for the backing file. |
||||
|
||||
References: https://bugzilla.redhat.com/show_bug.cgi?id=950497 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libmount/src/context_umount.c | 7 ++++++- |
||||
1 file changed, 6 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c |
||||
index 2b791c4..b02902c 100644 |
||||
--- a/libmount/src/context_umount.c |
||||
+++ b/libmount/src/context_umount.c |
||||
@@ -161,7 +161,12 @@ try_loopdev: |
||||
struct stat st; |
||||
|
||||
if (stat(tgt, &st) == 0 && S_ISREG(st.st_mode)) { |
||||
- int count = loopdev_count_by_backing_file(tgt, &loopdev); |
||||
+ int count; |
||||
+ |
||||
+ cn_tgt = mnt_resolve_path(tgt, cache); |
||||
+ count = loopdev_count_by_backing_file(cn_tgt, &loopdev); |
||||
+ if (!cache) |
||||
+ free(cn_tgt); |
||||
if (count == 1) { |
||||
DBG(CXT, mnt_debug_h(cxt, |
||||
"umount: %s --> %s (retry)", tgt, loopdev)); |
||||
-- |
||||
1.8.1.4 |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
diff -up util-linux-2.23.2/libmount/src/context_umount.c.kzak util-linux-2.23.2/libmount/src/context_umount.c |
||||
--- util-linux-2.23.2/libmount/src/context_umount.c.kzak 2013-10-07 11:43:10.990598629 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/context_umount.c 2013-10-07 11:46:01.051031431 +0200 |
||||
@@ -423,6 +423,8 @@ static int evaluate_permissions(struct l |
||||
if (optstr && !mnt_optstr_get_option(optstr, |
||||
"user", &mtab_user, &sz) && sz) |
||||
ok = !strncmp(curr_user, mtab_user, sz); |
||||
+ |
||||
+ free(curr_user); |
||||
} |
||||
|
||||
if (ok) { |
||||
diff -up util-linux-2.23.2/libmount/src/utils.c.kzak util-linux-2.23.2/libmount/src/utils.c |
||||
--- util-linux-2.23.2/libmount/src/utils.c.kzak 2013-07-30 11:15:27.391515623 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/utils.c 2013-10-07 11:43:27.209924834 +0200 |
||||
@@ -159,7 +159,7 @@ int mnt_chdir_to_parent(const char *targ |
||||
if (!last || !*last) |
||||
memcpy(*filename, ".", 2); |
||||
else |
||||
- memcpy(*filename, last, strlen(last) + 1); |
||||
+ memmove(*filename, last, strlen(last) + 1); |
||||
} else |
||||
free(buf); |
||||
return 0; |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
diff -up util-linux-2.23.2/include/loopdev.h.kzak util-linux-2.23.2/include/loopdev.h |
||||
--- util-linux-2.23.2/include/loopdev.h.kzak 2013-06-13 09:46:10.397650425 +0200 |
||||
+++ util-linux-2.23.2/include/loopdev.h 2014-01-14 11:11:48.427643690 +0100 |
||||
@@ -149,6 +149,7 @@ extern void loopcxt_enable_debug(struct |
||||
extern int loopcxt_set_device(struct loopdev_cxt *lc, const char *device) |
||||
__attribute__ ((warn_unused_result)); |
||||
extern int loopcxt_has_device(struct loopdev_cxt *lc); |
||||
+extern int loopcxt_add_device(struct loopdev_cxt *lc); |
||||
extern char *loopcxt_strdup_device(struct loopdev_cxt *lc); |
||||
extern const char *loopcxt_get_device(struct loopdev_cxt *lc); |
||||
extern struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc); |
||||
diff -up util-linux-2.23.2/lib/loopdev.c.kzak util-linux-2.23.2/lib/loopdev.c |
||||
--- util-linux-2.23.2/lib/loopdev.c.kzak 2013-07-30 11:19:20.143600300 +0200 |
||||
+++ util-linux-2.23.2/lib/loopdev.c 2014-01-14 11:11:48.428643700 +0100 |
||||
@@ -1298,6 +1298,36 @@ int loopcxt_delete_device(struct loopdev |
||||
return 0; |
||||
} |
||||
|
||||
+int loopcxt_add_device(struct loopdev_cxt *lc) |
||||
+{ |
||||
+ int rc = -EINVAL; |
||||
+ int ctl, nr = -1; |
||||
+ const char *p, *dev = loopcxt_get_device(lc); |
||||
+ |
||||
+ if (!dev) |
||||
+ goto done; |
||||
+ |
||||
+ if (!(lc->flags & LOOPDEV_FL_CONTROL)) { |
||||
+ rc = -ENOSYS; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
+ p = strrchr(dev, '/'); |
||||
+ if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1) |
||||
+ || nr < 0) |
||||
+ goto done; |
||||
+ |
||||
+ ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC); |
||||
+ if (ctl >= 0) { |
||||
+ DBG(lc, loopdev_debug("add_device %d", nr)); |
||||
+ rc = ioctl(ctl, LOOP_CTL_ADD, nr); |
||||
+ close(ctl); |
||||
+ } |
||||
+done: |
||||
+ DBG(lc, loopdev_debug("add_device done [rc=%d]", rc)); |
||||
+ return rc; |
||||
+} |
||||
+ |
||||
/* |
||||
* Note that LOOP_CTL_GET_FREE ioctl is supported since kernel 3.1. In older |
||||
* kernels we have to check all loop devices to found unused one. |
||||
diff -up util-linux-2.23.2/sys-utils/losetup.c.kzak util-linux-2.23.2/sys-utils/losetup.c |
||||
--- util-linux-2.23.2/sys-utils/losetup.c.kzak 2013-07-30 11:20:16.987117853 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/losetup.c 2014-01-14 11:11:48.428643700 +0100 |
||||
@@ -600,6 +600,8 @@ int main(int argc, char **argv) |
||||
{ |
||||
int hasdev = loopcxt_has_device(&lc); |
||||
|
||||
+ if (hasdev && !is_loopdev(loopcxt_get_device(&lc))) |
||||
+ loopcxt_add_device(&lc); |
||||
do { |
||||
const char *errpre; |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
diff -up util-linux-2.23.2/lib/loopdev.c.kzak util-linux-2.23.2/lib/loopdev.c |
||||
--- util-linux-2.23.2/lib/loopdev.c.kzak 2014-09-25 10:16:23.521897462 +0200 |
||||
+++ util-linux-2.23.2/lib/loopdev.c 2014-09-25 10:23:38.852050990 +0200 |
||||
@@ -1129,6 +1129,12 @@ static int loopcxt_check_size(struct loo |
||||
return -errno; |
||||
} |
||||
|
||||
+ /* It's block device, so, align to 512-byte sectors */ |
||||
+ if (expected_size % 512) { |
||||
+ DBG(lc, loopdev_debug("expected size misaligned to 512-byte sectors")); |
||||
+ expected_size = (expected_size >> 9) << 9; |
||||
+ } |
||||
+ |
||||
if (expected_size != size) { |
||||
DBG(lc, loopdev_debug("warning: loopdev and expected " |
||||
"size dismatch (%ju/%ju)", |
||||
diff -up util-linux-2.23.2/sys-utils/losetup.c.kzak util-linux-2.23.2/sys-utils/losetup.c |
||||
--- util-linux-2.23.2/sys-utils/losetup.c.kzak 2014-09-25 10:16:23.521897462 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/losetup.c 2014-09-25 10:23:38.852050990 +0200 |
||||
@@ -632,11 +632,7 @@ int main(int argc, char **argv) |
||||
/* errors */ |
||||
errpre = hasdev && loopcxt_get_fd(&lc) < 0 ? |
||||
loopcxt_get_device(&lc) : file; |
||||
- if (errno == ERANGE && offset && offset % 512) |
||||
- warnx(_("%s: failed to set up loop device, " |
||||
- "offset is not 512-byte aligned."), errpre); |
||||
- else |
||||
- warn(_("%s: failed to set up loop device"), errpre); |
||||
+ warn(_("%s: failed to set up loop device"), errpre); |
||||
break; |
||||
} while (hasdev == 0); |
@ -0,0 +1,130 @@
@@ -0,0 +1,130 @@
|
||||
From 5cc378e4cdeb957b405e0264a09295eda7d75ff7 Mon Sep 17 00:00:00 2001 |
||||
From: Scott Moser <smoser@ubuntu.com> |
||||
Date: Mon, 13 Jan 2014 15:32:49 -0500 |
||||
Subject: [PATCH] partx: fix --update ranges and out of order tables |
||||
|
||||
partx --update DEVICE NUMBER |
||||
was broken in 2 cases: |
||||
* if NUMBER != 1 |
||||
* if the partition table was "out of order". |
||||
Ie, where sda2 came after sda3. |
||||
|
||||
References: https://bugs.launchpad.net/ubuntu/+source/cloud-utils/+bug/1244662 |
||||
Signed-off-by: Scott Moser <smoser@ubuntu.com> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
disk-utils/partx.c | 75 ++++++++++++++++++++++++++++++++++++------------------ |
||||
1 file changed, 50 insertions(+), 25 deletions(-) |
||||
|
||||
diff --git a/disk-utils/partx.c b/disk-utils/partx.c |
||||
index 880d779..df03e59 100644 |
||||
--- a/disk-utils/partx.c |
||||
+++ b/disk-utils/partx.c |
||||
@@ -412,10 +412,41 @@ static void upd_parts_warnx(const char *device, int first, int last) |
||||
device, first, last); |
||||
} |
||||
|
||||
+/** |
||||
+ * get_partition_by_partno: |
||||
+ * @ls: partitions list |
||||
+ * @n: the partition number (e.g. 'N' from sda'N') |
||||
+ * |
||||
+ * This does not assume any order of the input blkid_partlist. |
||||
+ * And correctly handles "out of order" partition tables. |
||||
+ * partition N is located after partition N+1 on the disk. |
||||
+ * |
||||
+ * Returns: partition object or NULL in case or error. |
||||
+ */ |
||||
+blkid_partition get_partition_by_partno(blkid_partlist ls, int n) |
||||
+{ |
||||
+ int i, nparts; |
||||
+ blkid_partition par; |
||||
+ if (!ls) |
||||
+ return NULL; |
||||
+ |
||||
+ nparts = blkid_partlist_numof_partitions(ls); |
||||
+ if (nparts < 0) |
||||
+ return NULL; |
||||
+ |
||||
+ for (i = 0; i < nparts; i++) { |
||||
+ par = blkid_partlist_get_partition(ls, i); |
||||
+ if (n == blkid_partition_get_partno(par)) { |
||||
+ return par; |
||||
+ } |
||||
+ } |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
static int upd_parts(int fd, const char *device, dev_t devno, |
||||
blkid_partlist ls, int lower, int upper) |
||||
{ |
||||
- int i, n, an, nparts, rc = 0, errfirst = 0, errlast = 0, err; |
||||
+ int n, nparts, rc = 0, errfirst = 0, errlast = 0, err; |
||||
blkid_partition par; |
||||
uintmax_t start, size; |
||||
|
||||
@@ -441,18 +472,16 @@ static int upd_parts(int fd, const char *device, dev_t devno, |
||||
return -1; |
||||
} |
||||
|
||||
- for (i = 0, n = lower; n <= upper; n++) { |
||||
- par = blkid_partlist_get_partition(ls, i); |
||||
- an = blkid_partition_get_partno(par); |
||||
- |
||||
- if (lower && n < lower) |
||||
- continue; |
||||
- if (upper && n > upper) |
||||
+ for (n = lower; n <= upper; n++) { |
||||
+ par = get_partition_by_partno(ls, n); |
||||
+ if (!par) { |
||||
+ if (verbose) |
||||
+ warn(_("%s: no partition #%d"), device, n); |
||||
continue; |
||||
+ } |
||||
|
||||
start = blkid_partition_get_start(par); |
||||
size = blkid_partition_get_size(par); |
||||
- |
||||
if (blkid_partition_is_extended(par)) |
||||
/* |
||||
* Let's follow the Linux kernel and reduce |
||||
@@ -463,25 +492,21 @@ static int upd_parts(int fd, const char *device, dev_t devno, |
||||
err = partx_del_partition(fd, n); |
||||
if (err == -1 && errno == ENXIO) |
||||
err = 0; /* good, it already doesn't exist */ |
||||
- if (an == n) |
||||
+ if (err == -1 && errno == EBUSY) |
||||
{ |
||||
- if (i < nparts) |
||||
- i++; |
||||
- if (err == -1 && errno == EBUSY) |
||||
- { |
||||
- /* try to resize */ |
||||
- err = partx_resize_partition(fd, n, start, size); |
||||
- if (verbose) |
||||
- printf(_("%s: partition #%d resized\n"), device, n); |
||||
- if (err == 0) |
||||
- continue; |
||||
- } |
||||
- if (err == 0 && partx_add_partition(fd, n, start, size) == 0) { |
||||
- if (verbose) |
||||
- printf(_("%s: partition #%d added\n"), device, n); |
||||
+ /* try to resize */ |
||||
+ err = partx_resize_partition(fd, n, start, size); |
||||
+ if (verbose) |
||||
+ printf(_("%s: partition #%d resized\n"), device, n); |
||||
+ if (err == 0) |
||||
continue; |
||||
- } |
||||
} |
||||
+ if (err == 0 && partx_add_partition(fd, n, start, size) == 0) { |
||||
+ if (verbose) |
||||
+ printf(_("%s: partition #%d added\n"), device, n); |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
if (err == 0) |
||||
continue; |
||||
rc = -1; |
||||
-- |
||||
1.9.3 |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
diff -up util-linux-2.23.2/fdisks/sfdisk.c.kzak util-linux-2.23.2/fdisks/sfdisk.c |
||||
--- util-linux-2.23.2/fdisks/sfdisk.c.kzak 2013-07-30 10:39:26.200738180 +0200 |
||||
+++ util-linux-2.23.2/fdisks/sfdisk.c 2013-10-07 11:52:10.701445115 +0200 |
||||
@@ -3201,9 +3201,9 @@ do_fdisk(char *dev) { |
||||
ignore_result( fgets(answer, sizeof(answer), stdin) ); |
||||
if (answer[0] == 'q' || answer[0] == 'Q') { |
||||
errx(EXIT_FAILURE, _("Quitting - nothing changed")); |
||||
- } else if (rpmatch(answer) == 1) { |
||||
- continue; |
||||
} else if (rpmatch(answer) == 0) { |
||||
+ continue; |
||||
+ } else if (rpmatch(answer) == 1) { |
||||
break; |
||||
} else { |
||||
printf(_("Please answer one of y,n,q\n")); |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
From 9b5dc4cb8d5d82c31c0cda898832998c21afc303 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 9 Sep 2013 12:24:01 +0200 |
||||
Subject: [PATCH] su: fix lastlog and btmp logging |
||||
|
||||
The su(1) logging code mix ups "old" and "new" passwd structs. The |
||||
result is things like |
||||
|
||||
Sep 9 11:50:45 x2 su: (to kzak) kzak on none |
||||
|
||||
in /var/log/messages. The right log entry is |
||||
|
||||
Sep 9 11:50:45 x2 su: (to root) kzak on pts/3 |
||||
|
||||
The bug has been introduced by commit c74a7af17c7a176c358dfaa8e1814786c89ebc14. |
||||
|
||||
References: https://bugzilla.redhat.com/show_bug.cgi?id=1005194 |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
login-utils/su-common.c | 5 +---- |
||||
1 file changed, 1 insertion(+), 4 deletions(-) |
||||
|
||||
diff --git a/login-utils/su-common.c b/login-utils/su-common.c |
||||
index ade5c92..858af01 100644 |
||||
--- a/login-utils/su-common.c |
||||
+++ b/login-utils/su-common.c |
||||
@@ -161,7 +161,7 @@ log_syslog(struct passwd const *pw, bool successful) |
||||
old_user = pwd ? pwd->pw_name : ""; |
||||
} |
||||
|
||||
- if (get_terminal_name(STDERR_FILENO, NULL, &tty, NULL) == 0 && tty) |
||||
+ if (get_terminal_name(STDERR_FILENO, NULL, &tty, NULL) != 0 || !tty) |
||||
tty = "none"; |
||||
|
||||
openlog (program_invocation_short_name, 0 , LOG_AUTH); |
||||
@@ -483,9 +483,6 @@ authenticate (const struct passwd *pw) |
||||
|
||||
done: |
||||
|
||||
- if (lpw && lpw->pw_name) |
||||
- pw = lpw; |
||||
- |
||||
log_syslog(pw, !is_pam_failure(retval)); |
||||
|
||||
if (is_pam_failure(retval)) |
||||
-- |
||||
1.8.1.4 |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
diff -up util-linux-2.23.2/login-utils/su-common.c.kzak util-linux-2.23.2/login-utils/su-common.c |
||||
--- util-linux-2.23.2/login-utils/su-common.c.kzak 2013-07-30 10:39:26.223738407 +0200 |
||||
+++ util-linux-2.23.2/login-utils/su-common.c 2013-09-09 09:32:05.497238691 +0200 |
||||
@@ -111,6 +111,9 @@ static int same_session = 0; |
||||
/* SU_MODE_{RUNUSER,SU} */ |
||||
static int su_mode; |
||||
|
||||
+/* Don't print PAM info messages (Last login, etc.). */ |
||||
+static int suppress_pam_info; |
||||
+ |
||||
static bool _pam_session_opened; |
||||
static bool _pam_cred_established; |
||||
static sig_atomic_t volatile caught_signal = false; |
||||
@@ -208,10 +211,23 @@ static void log_btmp(struct passwd const |
||||
updwtmp(_PATH_BTMP, &ut); |
||||
} |
||||
|
||||
+ |
||||
+static int su_pam_conv(int num_msg, const struct pam_message **msg, |
||||
+ struct pam_response **resp, void *appdata_ptr) |
||||
+{ |
||||
+ if (suppress_pam_info |
||||
+ && num_msg == 1 |
||||
+ && msg |
||||
+ && msg[0]->msg_style == PAM_TEXT_INFO) |
||||
+ return PAM_SUCCESS; |
||||
+ |
||||
+ return misc_conv(num_msg, msg, resp, appdata_ptr); |
||||
+} |
||||
+ |
||||
static struct pam_conv conv = |
||||
{ |
||||
- misc_conv, |
||||
- NULL |
||||
+ su_pam_conv, |
||||
+ NULL |
||||
}; |
||||
|
||||
static void |
||||
@@ -902,6 +918,9 @@ su_main (int argc, char **argv, int mode |
||||
|
||||
init_groups (pw, groups, num_supp_groups); |
||||
|
||||
+ if (!simulate_login || command) |
||||
+ suppress_pam_info = 1; /* don't print PAM info messages */ |
||||
+ |
||||
create_watching_parent (); |
||||
/* Now we're in the child. */ |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
diff -up util-linux-2.23.2/tests/functions.sh.kzak util-linux-2.23.2/tests/functions.sh |
||||
--- util-linux-2.23.2/tests/functions.sh.kzak 2013-06-13 09:46:10.554651768 +0200 |
||||
+++ util-linux-2.23.2/tests/functions.sh 2013-09-09 10:01:23.355469268 +0200 |
||||
@@ -483,7 +483,7 @@ function ts_scsi_debug_init { |
||||
modprobe scsi_debug $* |
||||
[ "$?" == 0 ] || ts_die "Cannot init device" |
||||
|
||||
- DEVNAME=$(grep scsi_debug /sys/block/*/device/model | awk -F '/' '{print $4}') |
||||
+ DEVNAME=$(grep --with-filename scsi_debug /sys/block/*/device/model | awk -F '/' '{print $4}') |
||||
[ "x${DEVNAME}" == "x" ] && ts_die "Cannot find device" |
||||
|
||||
DEVICE="/dev/${DEVNAME}" |
||||
diff -up util-linux-2.23.2/tests/ts/cramfs/mkfs.kzak util-linux-2.23.2/tests/ts/cramfs/mkfs |
||||
--- util-linux-2.23.2/tests/ts/cramfs/mkfs.kzak 2013-06-13 09:46:10.557651793 +0200 |
||||
+++ util-linux-2.23.2/tests/ts/cramfs/mkfs 2013-09-09 10:01:23.355469268 +0200 |
||||
@@ -80,7 +80,7 @@ cd $TS_MOUNTPOINT |
||||
|
||||
ts_log "list the image" |
||||
export TZ='GMT-1' |
||||
-ls -laR --time-style=long-iso . >> $TS_OUTPUT |
||||
+ls -laR --time-style=long-iso . | sed 's:\. : :g' >> $TS_OUTPUT |
||||
echo >> $TS_OUTPUT |
||||
|
||||
ts_log "list checksums from new data" |
||||
diff -up util-linux-2.23.2/tests/ts/libmount/context-utab.kzak util-linux-2.23.2/tests/ts/libmount/context-utab |
||||
--- util-linux-2.23.2/tests/ts/libmount/context-utab.kzak 2013-06-13 09:46:10.561651827 +0200 |
||||
+++ util-linux-2.23.2/tests/ts/libmount/context-utab 2013-09-09 10:01:23.355469268 +0200 |
||||
@@ -85,7 +85,9 @@ grep -q $DEVICE $LIBMOUNT_UTAB && \ |
||||
echo "umount (mountpoint) failed: found $DEVICE in $LIBMOUNT_UTAB" >> $TS_OUTPUT 2>&1 |
||||
ts_finalize_subtest |
||||
|
||||
+ |
||||
if [ -x "/sbin/mkfs.btrfs" ]; then |
||||
+ $TS_CMD_WIPEFS -a $DEVICE &> /dev/null |
||||
ts_log "Create filesystem [btrfs]" |
||||
/sbin/mkfs.btrfs -L "$LABEL" $DEVICE &> /dev/null |
||||
udevadm settle |
@ -0,0 +1,248 @@
@@ -0,0 +1,248 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am |
||||
--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak 2014-09-25 14:16:33.526384729 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/Makemodule.am 2014-09-25 14:15:34.861825005 +0200 |
||||
@@ -290,6 +290,7 @@ usrbin_exec_PROGRAMS += unshare |
||||
dist_man_MANS += sys-utils/unshare.1 |
||||
unshare_SOURCES = sys-utils/unshare.c |
||||
unshare_LDADD = $(LDADD) libcommon.la |
||||
+unshare_CFLAGS = $(AM_CFLAGS) -I$(ul_libmount_incdir) |
||||
endif |
||||
|
||||
if BUILD_NSENTER |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.1.kzak util-linux-2.23.2/sys-utils/unshare.1 |
||||
--- util-linux-2.23.2/sys-utils/unshare.1.kzak 2014-09-25 14:14:30.194208005 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.1 2014-09-25 14:15:17.617660476 +0200 |
||||
@@ -1,63 +1,82 @@ |
||||
.\" Process this file with |
||||
.\" groff -man -Tascii lscpu.1 |
||||
.\" |
||||
-.TH UNSHARE 1 "January 2013" "util-linux" "User Commands" |
||||
+.TH UNSHARE 1 "July 2013" "util-linux" "User Commands" |
||||
.SH NAME |
||||
unshare \- run program with some namespaces unshared from parent |
||||
.SH SYNOPSIS |
||||
.B unshare |
||||
.RI [ options ] |
||||
-program |
||||
+.I program |
||||
.RI [ arguments ] |
||||
.SH DESCRIPTION |
||||
-Unshares specified namespaces from parent process and then executes specified |
||||
-program. Unshareable namespaces are: |
||||
+Unshares the indicated namespaces from the parent process and then executes |
||||
+the specified program. The namespaces to be unshared are indicated via |
||||
+options. Unshareable namespaces are: |
||||
.TP |
||||
.BR "mount namespace" |
||||
-mounting and unmounting filesystems will not affect rest of the system |
||||
+Mounting and unmounting filesystems will not affect the rest of the system |
||||
(\fBCLONE_NEWNS\fP flag), except for filesystems which are explicitly marked as |
||||
-shared (by mount --make-shared). See /proc/self/mountinfo for the shared flags. |
||||
+shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP for the |
||||
+\fBshared\fP flags). |
||||
+ |
||||
+It's recommended to use \fBmount --make-rprivate\fP or \fBmount --make-rslave\fP |
||||
+after \fBunshare --mount\fP to make sure that mountpoints in the new namespace |
||||
+are really unshared from parental namespace. |
||||
.TP |
||||
.BR "UTS namespace" |
||||
-setting hostname, domainname will not affect rest of the system |
||||
-(\fBCLONE_NEWUTS\fP flag). |
||||
+Setting hostname or domainname will not affect the rest of the system. |
||||
+(\fBCLONE_NEWUTS\fP flag) |
||||
.TP |
||||
.BR "IPC namespace" |
||||
-process will have independent namespace for System V message queues, semaphore |
||||
-sets and shared memory segments (\fBCLONE_NEWIPC\fP flag). |
||||
+The process will have an independent namespace for System V message queues, |
||||
+semaphore sets and shared memory segments. (\fBCLONE_NEWIPC\fP flag) |
||||
.TP |
||||
.BR "network namespace" |
||||
-process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall |
||||
-rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets |
||||
-etc. (\fBCLONE_NEWNET\fP flag). |
||||
+The process will have independent IPv4 and IPv6 stacks, IP routing tables, |
||||
+firewall rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, |
||||
+sockets, etc. (\fBCLONE_NEWNET\fP flag) |
||||
.TP |
||||
.BR "pid namespace" |
||||
-children will have a distinct set of pid to process mappings than their parent. |
||||
-(\fBCLONE_NEWPID\fP flag). |
||||
+Children will have a distinct set of PID to process mappings from their parent. |
||||
+(\fBCLONE_NEWPID\fP flag) |
||||
.PP |
||||
-See the \fBclone\fR(2) for exact semantics of the flags. |
||||
+See \fBclone\fR(2) for the exact semantics of the flags. |
||||
.SH OPTIONS |
||||
.TP |
||||
.BR \-h , " \-\-help" |
||||
-Print a help message, |
||||
-.TP |
||||
-.BR \-m , " \-\-mount" |
||||
-Unshare the mount namespace, |
||||
-.TP |
||||
-.BR \-u , " \-\-uts" |
||||
-Unshare the UTS namespace, |
||||
+Display help text and exit. |
||||
.TP |
||||
.BR \-i , " \-\-ipc" |
||||
-Unshare the IPC namespace, |
||||
+Unshare the IPC namespace. |
||||
+.TP |
||||
+.BR \-m , " \-\-mount" |
||||
+Unshare the mount namespace. |
||||
.TP |
||||
.BR \-n , " \-\-net" |
||||
Unshare the network namespace. |
||||
.TP |
||||
.BR \-p , " \-\-pid" |
||||
Unshare the pid namespace. |
||||
+See also the \fB--fork\fP and \fB--mount-proc\fP options. |
||||
+.TP |
||||
+.BR \-u , " \-\-uts" |
||||
+Unshare the UTS namespace. |
||||
+.TP |
||||
+.BR \-f , " \-\-fork" |
||||
+Fork the specified \fIprogram\fR as a child process of \fBunshare\fR rather than |
||||
+running it directly. This is useful when creating a new pid namespace. |
||||
+.TP |
||||
+.BR \-\-mount-proc "[=\fImountpoint\fP]" |
||||
+Just before running the program, mount the proc filesystem at the \fImountpoint\fP |
||||
+(default is /proc). This is useful when creating a new pid namespace. It also |
||||
+implies creating a new mount namespace since the /proc mount would otherwise |
||||
+mess up existing programs on the system. The new proc filesystem is explicitly |
||||
+mounted as private (by MS_PRIVATE|MS_REC). |
||||
.SH SEE ALSO |
||||
.BR unshare (2), |
||||
-.BR clone (2) |
||||
+.BR clone (2), |
||||
+.BR mount (8) |
||||
.SH BUGS |
||||
None known so far. |
||||
.SH AUTHOR |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.c.kzak util-linux-2.23.2/sys-utils/unshare.c |
||||
--- util-linux-2.23.2/sys-utils/unshare.c.kzak 2014-09-25 14:14:30.194208005 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.c 2014-09-25 14:15:34.861825005 +0200 |
||||
@@ -24,12 +24,19 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <unistd.h> |
||||
+#include <sys/wait.h> |
||||
+#include <sys/mount.h> |
||||
+ |
||||
+/* we only need some defines missing in sys/mount.h, no libmount linkage */ |
||||
+#include <libmount.h> |
||||
|
||||
#include "nls.h" |
||||
#include "c.h" |
||||
-#include "closestream.h" |
||||
#include "namespace.h" |
||||
#include "exec_shell.h" |
||||
+#include "xalloc.h" |
||||
+#include "pathnames.h" |
||||
+ |
||||
|
||||
static void usage(int status) |
||||
{ |
||||
@@ -40,11 +47,13 @@ static void usage(int status) |
||||
_(" %s [options] <program> [args...]\n"), program_invocation_short_name); |
||||
|
||||
fputs(USAGE_OPTIONS, out); |
||||
- fputs(_(" -m, --mount unshare mounts namespace\n"), out); |
||||
- fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); |
||||
- fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
||||
- fputs(_(" -n, --net unshare network namespace\n"), out); |
||||
- fputs(_(" -p, --pid unshare pid namespace\n"), out); |
||||
+ fputs(_(" -m, --mount unshare mounts namespace\n"), out); |
||||
+ fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); |
||||
+ fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
||||
+ fputs(_(" -n, --net unshare network namespace\n"), out); |
||||
+ fputs(_(" -p, --pid unshare pid namespace\n"), out); |
||||
+ fputs(_(" -f, --fork fork before launching <program>\n"), out); |
||||
+ fputs(_(" --mount-proc[=<dir>] mount proc filesystem first (implies --mount)\n"), out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
@@ -56,6 +65,9 @@ static void usage(int status) |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
+ enum { |
||||
+ OPT_MOUNTPROC = CHAR_MAX + 1 |
||||
+ }; |
||||
static const struct option longopts[] = { |
||||
{ "help", no_argument, 0, 'h' }, |
||||
{ "version", no_argument, 0, 'V'}, |
||||
@@ -64,20 +76,24 @@ int main(int argc, char *argv[]) |
||||
{ "ipc", no_argument, 0, 'i' }, |
||||
{ "net", no_argument, 0, 'n' }, |
||||
{ "pid", no_argument, 0, 'p' }, |
||||
+ { "fork", no_argument, 0, 'f' }, |
||||
+ { "mount-proc", optional_argument, 0, OPT_MOUNTPROC }, |
||||
{ NULL, 0, 0, 0 } |
||||
}; |
||||
|
||||
int unshare_flags = 0; |
||||
+ int c, forkit = 0; |
||||
+ const char *procmnt = NULL; |
||||
|
||||
- int c; |
||||
- |
||||
- setlocale(LC_MESSAGES, ""); |
||||
+ setlocale(LC_ALL, ""); |
||||
bindtextdomain(PACKAGE, LOCALEDIR); |
||||
textdomain(PACKAGE); |
||||
- atexit(close_stdout); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "hVmuinp", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "+fhVmuinp", longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
+ case 'f': |
||||
+ forkit = 1; |
||||
+ break; |
||||
case 'h': |
||||
usage(EXIT_SUCCESS); |
||||
case 'V': |
||||
@@ -98,6 +114,10 @@ int main(int argc, char *argv[]) |
||||
case 'p': |
||||
unshare_flags |= CLONE_NEWPID; |
||||
break; |
||||
+ case OPT_MOUNTPROC: |
||||
+ unshare_flags |= CLONE_NEWNS; |
||||
+ procmnt = optarg ? optarg : "/proc"; |
||||
+ break; |
||||
default: |
||||
usage(EXIT_FAILURE); |
||||
} |
||||
@@ -106,6 +126,31 @@ int main(int argc, char *argv[]) |
||||
if (-1 == unshare(unshare_flags)) |
||||
err(EXIT_FAILURE, _("unshare failed")); |
||||
|
||||
+ if (forkit) { |
||||
+ int status; |
||||
+ pid_t pid = fork(); |
||||
+ |
||||
+ switch(pid) { |
||||
+ case -1: |
||||
+ err(EXIT_FAILURE, _("fork failed")); |
||||
+ case 0: /* child */ |
||||
+ break; |
||||
+ default: /* parent */ |
||||
+ if (waitpid(pid, &status, 0) == -1) |
||||
+ err(EXIT_FAILURE, _("waitpid failed")); |
||||
+ if (WIFEXITED(status)) |
||||
+ return WEXITSTATUS(status); |
||||
+ else if (WIFSIGNALED(status)) |
||||
+ kill(getpid(), WTERMSIG(status)); |
||||
+ err(EXIT_FAILURE, _("child exit failed")); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (procmnt && |
||||
+ (mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 || |
||||
+ mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0)) |
||||
+ err(EXIT_FAILURE, _("mount %s failed"), procmnt); |
||||
+ |
||||
if (optind < argc) { |
||||
execvp(argv[optind], argv + optind); |
||||
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]); |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
diff -up util-linux-2.23.2/login-utils/utmpdump.c.kzak util-linux-2.23.2/login-utils/utmpdump.c |
||||
--- util-linux-2.23.2/login-utils/utmpdump.c.kzak 2013-10-07 11:56:02.030191040 +0200 |
||||
+++ util-linux-2.23.2/login-utils/utmpdump.c 2013-10-07 12:05:08.671171091 +0200 |
||||
@@ -85,11 +85,14 @@ static void xcleanse(char *s, int len) |
||||
|
||||
static void print_utline(struct utmp ut) |
||||
{ |
||||
- char *addr_string, *time_string; |
||||
- struct in_addr in; |
||||
+ const char *addr_string, *time_string; |
||||
+ char buffer[INET6_ADDRSTRLEN]; |
||||
+ |
||||
+ if (ut.ut_addr_v6[1] || ut.ut_addr_v6[2] || ut.ut_addr_v6[3]) |
||||
+ addr_string = inet_ntop(AF_INET6, &(ut.ut_addr_v6), buffer, sizeof(buffer)); |
||||
+ else |
||||
+ addr_string = inet_ntop(AF_INET, &(ut.ut_addr_v6), buffer, sizeof(buffer)); |
||||
|
||||
- in.s_addr = ut.ut_addr; |
||||
- addr_string = inet_ntoa(in); |
||||
time_string = timetostr(ut.ut_time); |
||||
cleanse(ut.ut_id); |
||||
cleanse(ut.ut_user); |
||||
@@ -97,7 +100,7 @@ static void print_utline(struct utmp ut) |
||||
cleanse(ut.ut_host); |
||||
|
||||
/* pid id user line host addr time */ |
||||
- printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15.15s] [%-28.28s]\n", |
||||
+ printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15s] [%-28.28s]\n", |
||||
ut.ut_type, ut.ut_pid, ut.ut_id, 8, UT_NAMESIZE, ut.ut_user, |
||||
12, UT_LINESIZE, ut.ut_line, 20, UT_HOSTSIZE, ut.ut_host, |
||||
addr_string, time_string); |
||||
@@ -248,11 +251,10 @@ static int gettok(char *line, char *dest |
||||
static void undump(FILE *fp) |
||||
{ |
||||
struct utmp ut; |
||||
- char s_addr[16], s_time[29], *linestart, *line; |
||||
+ char s_addr[INET6_ADDRSTRLEN + 1], s_time[29], *linestart, *line; |
||||
int count = 0; |
||||
|
||||
line = linestart = xmalloc(1024 * sizeof(*linestart)); |
||||
- s_addr[15] = 0; |
||||
s_time[28] = 0; |
||||
|
||||
while (fgets(linestart, 1023, fp)) { |
||||
@@ -267,7 +269,10 @@ static void undump(FILE *fp) |
||||
line += gettok(line, s_addr, sizeof(s_addr) - 1, 1); |
||||
line += gettok(line, s_time, sizeof(s_time) - 1, 0); |
||||
|
||||
- ut.ut_addr = inet_addr(s_addr); |
||||
+ if (strchr(s_addr, '.')) |
||||
+ inet_pton(AF_INET, s_addr, &(ut.ut_addr_v6)); |
||||
+ else |
||||
+ inet_pton(AF_INET6, s_addr, &(ut.ut_addr_v6)); |
||||
ut.ut_time = strtotime(s_time); |
||||
|
||||
ignore_result( fwrite(&ut, sizeof(ut), 1, stdout) ); |
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
diff -up util-linux-2.23.2/disk-utils/blockdev.c.kzak util-linux-2.23.2/disk-utils/blockdev.c |
||||
--- util-linux-2.23.2/disk-utils/blockdev.c.kzak 2015-06-23 11:29:27.818001654 +0200 |
||||
+++ util-linux-2.23.2/disk-utils/blockdev.c 2015-06-23 11:29:43.752884860 +0200 |
||||
@@ -16,6 +16,7 @@ |
||||
#include "blkdev.h" |
||||
#include "pathnames.h" |
||||
#include "closestream.h" |
||||
+#include "sysfs.h" |
||||
|
||||
struct bdc { |
||||
long ioc; /* ioctl code */ |
||||
@@ -364,7 +365,7 @@ static void do_commands(int fd, char **a |
||||
} |
||||
|
||||
if (res == -1) { |
||||
- perror(bdcms[j].iocname); |
||||
+ warn(_("ioctl error on %s"), bdcms[j].iocname); |
||||
if (verbose) |
||||
printf(_("%s failed.\n"), _(bdcms[j].help)); |
||||
exit(EXIT_FAILURE); |
||||
@@ -436,7 +437,8 @@ static void report_device(char *device, |
||||
int ro, ssz, bsz; |
||||
long ra; |
||||
unsigned long long bytes; |
||||
- struct hd_geometry g; |
||||
+ uint64_t start = 0; |
||||
+ struct stat st; |
||||
|
||||
fd = open(device, O_RDONLY | O_NONBLOCK); |
||||
if (fd < 0) { |
||||
@@ -446,15 +448,27 @@ static void report_device(char *device, |
||||
} |
||||
|
||||
ro = ssz = bsz = 0; |
||||
- g.start = ra = 0; |
||||
+ ra = 0; |
||||
+ if (fstat(fd, &st) == 0 && !sysfs_devno_is_wholedisk(st.st_rdev)) { |
||||
+ struct sysfs_cxt cxt; |
||||
+ |
||||
+ if (sysfs_init(&cxt, st.st_rdev, NULL)) |
||||
+ err(EXIT_FAILURE, |
||||
+ _("%s: failed to initialize sysfs handler"), |
||||
+ device); |
||||
+ if (sysfs_read_u64(&cxt, "start", &start)) |
||||
+ err(EXIT_FAILURE, |
||||
+ _("%s: failed to read partition start from sysfs"), |
||||
+ device); |
||||
+ sysfs_deinit(&cxt); |
||||
+ } |
||||
if (ioctl(fd, BLKROGET, &ro) == 0 && |
||||
ioctl(fd, BLKRAGET, &ra) == 0 && |
||||
ioctl(fd, BLKSSZGET, &ssz) == 0 && |
||||
ioctl(fd, BLKBSZGET, &bsz) == 0 && |
||||
- ioctl(fd, HDIO_GETGEO, &g) == 0 && |
||||
blkdev_get_size(fd, &bytes) == 0) { |
||||
- printf("%s %5ld %5d %5d %10ld %15lld %s\n", |
||||
- ro ? "ro" : "rw", ra, ssz, bsz, g.start, bytes, device); |
||||
+ printf("%s %5ld %5d %5d %10ju %15lld %s\n", |
||||
+ ro ? "ro" : "rw", ra, ssz, bsz, start, bytes, device); |
||||
} else { |
||||
if (!quiet) |
||||
warnx(_("ioctl error on %s"), device); |
||||
diff -up util-linux-2.23.2/include/sysfs.h.kzak util-linux-2.23.2/include/sysfs.h |
||||
--- util-linux-2.23.2/include/sysfs.h.kzak 2015-06-23 11:32:12.709793086 +0200 |
||||
+++ util-linux-2.23.2/include/sysfs.h 2015-06-23 11:32:31.909652361 +0200 |
||||
@@ -72,6 +72,7 @@ extern int sysfs_is_partition_dirent(DIR |
||||
|
||||
extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname, |
||||
size_t len, dev_t *diskdevno); |
||||
+extern int sysfs_devno_is_wholedisk(dev_t devno); |
||||
|
||||
extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, |
||||
int *c, int *t, int *l); |
||||
diff -up util-linux-2.23.2/lib/sysfs.c.kzak util-linux-2.23.2/lib/sysfs.c |
||||
--- util-linux-2.23.2/lib/sysfs.c.kzak 2015-06-23 11:31:32.166090250 +0200 |
||||
+++ util-linux-2.23.2/lib/sysfs.c 2015-06-23 11:31:59.684888551 +0200 |
||||
@@ -638,6 +638,18 @@ err: |
||||
return -1; |
||||
} |
||||
|
||||
+/* |
||||
+ * Return 0 or 1, or < 0 in case of error |
||||
+ */ |
||||
+int sysfs_devno_is_wholedisk(dev_t devno) |
||||
+{ |
||||
+ dev_t disk; |
||||
+ |
||||
+ if (sysfs_devno_to_wholedisk(devno, NULL, 0, &disk) != 0) |
||||
+ return -1; |
||||
+ |
||||
+ return devno == disk; |
||||
+} |
||||
|
||||
int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, int *c, int *t, int *l) |
||||
{ |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/dmesg.c.kzak util-linux-2.23.2/sys-utils/dmesg.c |
||||
--- util-linux-2.23.2/sys-utils/dmesg.c.kzak 2013-07-30 11:22:47.213494455 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/dmesg.c 2014-09-24 10:24:49.179371108 +0200 |
||||
@@ -991,6 +991,8 @@ static int init_kmsg(struct dmesg_contro |
||||
|
||||
if (!ctl->follow) |
||||
mode |= O_NONBLOCK; |
||||
+ else |
||||
+ setlinebuf(stdout); |
||||
|
||||
ctl->kmsg = open("/dev/kmsg", mode); |
||||
if (ctl->kmsg < 0) |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/flock.c.kzak util-linux-2.23.2/sys-utils/flock.c |
||||
--- util-linux-2.23.2/sys-utils/flock.c.kzak 2014-03-25 12:00:53.735361387 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/flock.c 2014-03-25 12:01:44.534886083 +0100 |
||||
@@ -250,6 +250,7 @@ int main(int argc, char *argv[]) |
||||
/* otherwise try again */ |
||||
continue; |
||||
case EIO: |
||||
+ case EBADF: /* since Linux 3.4 (commit 55725513) */ |
||||
/* Probably NFSv4 where flock() is emulated by fcntl(). |
||||
* Let's try to reopen in read-write mode. |
||||
*/ |
@ -0,0 +1,173 @@
@@ -0,0 +1,173 @@
|
||||
diff -up util-linux-2.23.2/disk-utils/fsck.c.kzak util-linux-2.23.2/disk-utils/fsck.c |
||||
--- util-linux-2.23.2/disk-utils/fsck.c.kzak 2014-03-25 12:52:33.429389852 +0100 |
||||
+++ util-linux-2.23.2/disk-utils/fsck.c 2014-03-25 12:56:27.126804792 +0100 |
||||
@@ -79,9 +79,7 @@ static const char *really_wanted[] = { |
||||
"ext4dev", |
||||
"jfs", |
||||
"reiserfs", |
||||
- "xiafs", |
||||
- "xfs", |
||||
- NULL |
||||
+ "xiafs" |
||||
}; |
||||
|
||||
/* |
||||
@@ -167,6 +165,19 @@ static int string_to_int(const char *s) |
||||
return (int) l; |
||||
} |
||||
|
||||
+/* Do we really really want to check this fs? */ |
||||
+static int fs_check_required(const char *type) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ for(i = 0; i < ARRAY_SIZE(really_wanted); i++) { |
||||
+ if (strcmp(type, really_wanted[i]) == 0) |
||||
+ return 1; |
||||
+ } |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
static int is_mounted(struct libmnt_fs *fs) |
||||
{ |
||||
int rc; |
||||
@@ -546,17 +557,17 @@ static void print_stats(struct fsck_inst |
||||
* Execute a particular fsck program, and link it into the list of |
||||
* child processes we are waiting for. |
||||
*/ |
||||
-static int execute(const char *type, struct libmnt_fs *fs, int interactive) |
||||
+static int execute(const char *progname, const char *progpath, |
||||
+ const char *type, struct libmnt_fs *fs, int interactive) |
||||
{ |
||||
- char *s, *argv[80], prog[80]; |
||||
+ char *argv[80]; |
||||
int argc, i; |
||||
struct fsck_instance *inst, *p; |
||||
pid_t pid; |
||||
|
||||
inst = xcalloc(1, sizeof(*inst)); |
||||
|
||||
- sprintf(prog, "fsck.%s", type); |
||||
- argv[0] = xstrdup(prog); |
||||
+ argv[0] = xstrdup(progname); |
||||
argc = 1; |
||||
|
||||
for (i=0; i <num_args; i++) |
||||
@@ -583,19 +594,12 @@ static int execute(const char *type, str |
||||
argv[argc++] = xstrdup(fs_get_device(fs)); |
||||
argv[argc] = 0; |
||||
|
||||
- s = find_fsck(prog); |
||||
- if (s == NULL) { |
||||
- warnx(_("%s: not found"), prog); |
||||
- free(inst); |
||||
- return ENOENT; |
||||
- } |
||||
- |
||||
if (verbose || noexecute) { |
||||
const char *tgt = mnt_fs_get_target(fs); |
||||
|
||||
if (!tgt) |
||||
tgt = fs_get_device(fs); |
||||
- printf("[%s (%d) -- %s] ", s, num_running, tgt); |
||||
+ printf("[%s (%d) -- %s] ", progpath, num_running, tgt); |
||||
for (i=0; i < argc; i++) |
||||
printf("%s ", argv[i]); |
||||
printf("\n"); |
||||
@@ -617,15 +621,15 @@ static int execute(const char *type, str |
||||
} else if (pid == 0) { |
||||
if (!interactive) |
||||
close(0); |
||||
- execv(s, argv); |
||||
- err(FSCK_EX_ERROR, _("%s: execute failed"), s); |
||||
+ execv(progpath, argv); |
||||
+ err(FSCK_EX_ERROR, _("%s: execute failed"), progpath); |
||||
} |
||||
|
||||
for (i=0; i < argc; i++) |
||||
free(argv[i]); |
||||
|
||||
inst->pid = pid; |
||||
- inst->prog = xstrdup(prog); |
||||
+ inst->prog = xstrdup(progname); |
||||
inst->type = xstrdup(type); |
||||
gettimeofday(&inst->start_time, NULL); |
||||
inst->next = NULL; |
||||
@@ -822,6 +826,7 @@ static int wait_many(int flags) |
||||
*/ |
||||
static int fsck_device(struct libmnt_fs *fs, int interactive) |
||||
{ |
||||
+ char progname[80], *progpath; |
||||
const char *type; |
||||
int retval; |
||||
|
||||
@@ -838,15 +843,27 @@ static int fsck_device(struct libmnt_fs |
||||
else |
||||
type = DEFAULT_FSTYPE; |
||||
|
||||
+ sprintf(progname, "fsck.%s", type); |
||||
+ progpath = find_fsck(progname); |
||||
+ if (progpath == NULL) { |
||||
+ if (fs_check_required(type)) { |
||||
+ retval = ENOENT; |
||||
+ goto err; |
||||
+ } |
||||
+ return 0; |
||||
+ } |
||||
+ |
||||
num_running++; |
||||
- retval = execute(type, fs, interactive); |
||||
+ retval = execute(progname, progpath, type, fs, interactive); |
||||
if (retval) { |
||||
- warnx(_("error %d while executing fsck.%s for %s"), |
||||
- retval, type, fs_get_device(fs)); |
||||
num_running--; |
||||
- return FSCK_EX_ERROR; |
||||
+ goto err; |
||||
} |
||||
return 0; |
||||
+err: |
||||
+ warnx(_("error %d (%m) while executing fsck.%s for %s"), |
||||
+ retval, type, fs_get_device(fs)); |
||||
+ return FSCK_EX_ERROR; |
||||
} |
||||
|
||||
|
||||
@@ -1014,8 +1031,7 @@ static int fs_ignored_type(struct libmnt |
||||
/* Check if we should ignore this filesystem. */ |
||||
static int ignore(struct libmnt_fs *fs) |
||||
{ |
||||
- const char **ip, *type; |
||||
- int wanted = 0; |
||||
+ const char *type; |
||||
|
||||
/* |
||||
* If the pass number is 0, ignore it. |
||||
@@ -1070,16 +1086,11 @@ static int ignore(struct libmnt_fs *fs) |
||||
if (fs_ignored_type(fs)) |
||||
return 1; |
||||
|
||||
- /* Do we really really want to check this fs? */ |
||||
- for(ip = really_wanted; *ip; ip++) |
||||
- if (strcmp(type, *ip) == 0) { |
||||
- wanted = 1; |
||||
- break; |
||||
- } |
||||
+ |
||||
|
||||
/* See if the <fsck.fs> program is available. */ |
||||
if (find_fsck(type) == NULL) { |
||||
- if (wanted) |
||||
+ if (fs_check_required(type)) |
||||
warnx(_("cannot check %s: fsck.%s not found"), |
||||
fs_get_device(fs), type); |
||||
return 1; |
||||
@@ -1557,7 +1568,6 @@ int main(int argc, char *argv[]) |
||||
fs = add_dummy_fs(devices[i]); |
||||
else if (fs_ignored_type(fs)) |
||||
continue; |
||||
- |
||||
if (ignore_mounted && is_mounted(fs)) |
||||
continue; |
||||
status |= fsck_device(fs, interactive); |
@ -0,0 +1,496 @@
@@ -0,0 +1,496 @@
|
||||
diff -up util-linux-2.23.2/libmount/src/libmount.h.in.kzak util-linux-2.23.2/libmount/src/libmount.h.in |
||||
--- util-linux-2.23.2/libmount/src/libmount.h.in.kzak 2015-06-23 11:54:00.510210784 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/libmount.h.in 2015-06-23 11:54:58.592785482 +0200 |
||||
@@ -420,6 +420,15 @@ extern int mnt_table_get_root_fs(struct |
||||
extern int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr, |
||||
struct libmnt_fs *fs); |
||||
|
||||
+enum { |
||||
+ MNT_UNIQ_FORWARD = (1 << 1), /* default is backward */ |
||||
+ MNT_UNIQ_KEEPTREE = (1 << 2) |
||||
+}; |
||||
+extern int mnt_table_uniq_fs(struct libmnt_table *tb, int flags, |
||||
+ int (*cmp)(struct libmnt_table *, |
||||
+ struct libmnt_fs *, |
||||
+ struct libmnt_fs *)); |
||||
+ |
||||
extern struct libmnt_fs *mnt_table_find_mountpoint(struct libmnt_table *tb, |
||||
const char *path, int direction); |
||||
extern struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, |
||||
diff -up util-linux-2.23.2/libmount/src/libmount.sym.kzak util-linux-2.23.2/libmount/src/libmount.sym |
||||
--- util-linux-2.23.2/libmount/src/libmount.sym.kzak 2015-06-23 11:56:47.259989779 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/libmount.sym 2015-06-23 11:56:17.681206366 +0200 |
||||
@@ -256,3 +256,9 @@ global: |
||||
mnt_context_find_umount_fs; |
||||
mnt_table_find_mountpoint; |
||||
} MOUNT_2.22; |
||||
+ |
||||
+/* backport from v2.25 to RHEL7 */ |
||||
+MOUNT_2.25 { |
||||
+ mnt_table_uniq_fs; |
||||
+} MOUNT_2.23; |
||||
+ |
||||
diff -up util-linux-2.23.2/libmount/src/tab.c.kzak util-linux-2.23.2/libmount/src/tab.c |
||||
--- util-linux-2.23.2/libmount/src/tab.c.kzak 2015-06-23 11:52:04.750058424 +0200 |
||||
+++ util-linux-2.23.2/libmount/src/tab.c 2015-06-23 11:53:26.109462680 +0200 |
||||
@@ -398,6 +398,93 @@ int mnt_table_find_next_fs(struct libmnt |
||||
return 1; |
||||
} |
||||
|
||||
+static int mnt_table_move_parent(struct libmnt_table *tb, int oldid, int newid) |
||||
+{ |
||||
+ struct libmnt_iter itr; |
||||
+ struct libmnt_fs *fs; |
||||
+ |
||||
+ if (!tb) |
||||
+ return -EINVAL; |
||||
+ if (list_empty(&tb->ents)) |
||||
+ return 0; |
||||
+ |
||||
+ |
||||
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD); |
||||
+ |
||||
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) { |
||||
+ if (fs->parent == oldid) |
||||
+ fs->parent = newid; |
||||
+ } |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+/** |
||||
+ * mnt_table_uniq_fs: |
||||
+ * @tb: table |
||||
+ * @flags: MNT_UNIQ_* |
||||
+ * @cmp: function to compare filesystems |
||||
+ * |
||||
+ * This function de-duplicate the @tb, but does not change order of the |
||||
+ * filesystems. The @cmp function has to return 0 if the filesystems are |
||||
+ * equal, otherwise non-zero. |
||||
+ * |
||||
+ * The default is to keep in the table later mounted filesystems (function uses |
||||
+ * backward mode iterator). |
||||
+ * |
||||
+ * @MNT_UNIQ_FORWARD: remove later mounted filesystems |
||||
+ * @MNT_UNIQ_KEEPTREE: keep parent->id relation ship stil valid |
||||
+ * |
||||
+ * Returns: negative number in case of error, or 0 o success. |
||||
+ */ |
||||
+int mnt_table_uniq_fs(struct libmnt_table *tb, int flags, |
||||
+ int (*cmp)(struct libmnt_table *, |
||||
+ struct libmnt_fs *, |
||||
+ struct libmnt_fs *)) |
||||
+{ |
||||
+ struct libmnt_iter itr; |
||||
+ struct libmnt_fs *fs; |
||||
+ int direction = MNT_ITER_BACKWARD; |
||||
+ |
||||
+ if (!tb || !cmp) |
||||
+ return -EINVAL; |
||||
+ if (list_empty(&tb->ents)) |
||||
+ return 0; |
||||
+ |
||||
+ if (flags & MNT_UNIQ_FORWARD) |
||||
+ direction = MNT_ITER_FORWARD; |
||||
+ |
||||
+ |
||||
+ mnt_reset_iter(&itr, direction); |
||||
+ |
||||
+ if ((flags & MNT_UNIQ_KEEPTREE) && !is_mountinfo(tb)) |
||||
+ flags &= ~MNT_UNIQ_KEEPTREE; |
||||
+ |
||||
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) { |
||||
+ int want = 1; |
||||
+ struct libmnt_iter xtr; |
||||
+ struct libmnt_fs *x; |
||||
+ |
||||
+ mnt_reset_iter(&xtr, direction); |
||||
+ while (want && mnt_table_next_fs(tb, &xtr, &x) == 0) { |
||||
+ if (fs == x) |
||||
+ break; |
||||
+ want = cmp(tb, x, fs) != 0; |
||||
+ } |
||||
+ |
||||
+ if (!want) { |
||||
+ if (flags & MNT_UNIQ_KEEPTREE) |
||||
+ mnt_table_move_parent(tb, mnt_fs_get_id(fs), |
||||
+ mnt_fs_get_parent_id(fs)); |
||||
+ |
||||
+ |
||||
+ |
||||
+ mnt_table_remove_fs(tb, fs); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
/** |
||||
* mnt_table_set_iter: |
||||
* @tb: tab pointer |
||||
diff -up util-linux-2.23.2/sys-utils/fstrim.c.kzak util-linux-2.23.2/sys-utils/fstrim.c |
||||
--- util-linux-2.23.2/sys-utils/fstrim.c.kzak 2013-06-13 09:46:10.535651605 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/fstrim.c 2015-06-23 11:57:59.435461283 +0200 |
||||
@@ -41,6 +41,11 @@ |
||||
#include "strutils.h" |
||||
#include "c.h" |
||||
#include "closestream.h" |
||||
+#include "pathnames.h" |
||||
+#include "sysfs.h" |
||||
+#include "exitcodes.h" |
||||
+ |
||||
+#include <libmount.h> |
||||
|
||||
#ifndef FITRIM |
||||
struct fstrim_range { |
||||
@@ -51,16 +56,216 @@ struct fstrim_range { |
||||
#define FITRIM _IOWR('X', 121, struct fstrim_range) |
||||
#endif |
||||
|
||||
+/* returns: 0 = success, 1 = unsupported, < 0 = error */ |
||||
+static int fstrim_filesystem(const char *path, struct fstrim_range *rangetpl, |
||||
+ int verbose) |
||||
+{ |
||||
+ int fd; |
||||
+ struct stat sb; |
||||
+ struct fstrim_range range; |
||||
+ |
||||
+ /* kernel modifies the range */ |
||||
+ memcpy(&range, rangetpl, sizeof(range)); |
||||
+ |
||||
+ fd = open(path, O_RDONLY); |
||||
+ if (fd < 0) { |
||||
+ warn(_("cannot open %s"), path); |
||||
+ return -1; |
||||
+ } |
||||
+ if (fstat(fd, &sb) == -1) { |
||||
+ warn(_("stat of %s failed"), path); |
||||
+ return -1; |
||||
+ } |
||||
+ if (!S_ISDIR(sb.st_mode)) { |
||||
+ warnx(_("%s: not a directory"), path); |
||||
+ return -1; |
||||
+ } |
||||
+ errno = 0; |
||||
+ if (ioctl(fd, FITRIM, &range)) { |
||||
+ int rc = errno == EOPNOTSUPP || errno == ENOTTY ? 1 : -1; |
||||
+ |
||||
+ if (rc != 1) |
||||
+ warn(_("%s: FITRIM ioctl failed"), path); |
||||
+ close(fd); |
||||
+ return rc; |
||||
+ } |
||||
+ |
||||
+ if (verbose) { |
||||
+ char *str = size_to_human_string( |
||||
+ SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE, |
||||
+ (uint64_t) range.len); |
||||
+ /* TRANSLATORS: The standard value here is a very large number. */ |
||||
+ printf(_("%s: %s (%" PRIu64 " bytes) trimmed\n"), |
||||
+ path, str, (uint64_t) range.len); |
||||
+ free(str); |
||||
+ } |
||||
+ close(fd); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+static int has_discard(const char *devname, struct sysfs_cxt *wholedisk) |
||||
+{ |
||||
+ struct sysfs_cxt cxt, *parent = NULL; |
||||
+ uint64_t dg = 0; |
||||
+ dev_t disk = 0, dev; |
||||
+ int rc; |
||||
+ |
||||
+ dev = sysfs_devname_to_devno(devname, NULL); |
||||
+ if (!dev) |
||||
+ return 1; |
||||
+ /* |
||||
+ * This is tricky to read the info from sys/, because the queue |
||||
+ * atrributes are provided for whole devices (disk) only. We're trying |
||||
+ * to reuse the whole-disk sysfs context to optimize this stuff (as |
||||
+ * system usually have just one disk only). |
||||
+ */ |
||||
+ if (sysfs_devno_to_wholedisk(dev, NULL, 0, &disk) || !disk) |
||||
+ return 1; |
||||
+ if (dev != disk) { |
||||
+ if (wholedisk->devno != disk) { |
||||
+ sysfs_deinit(wholedisk); |
||||
+ if (sysfs_init(wholedisk, disk, NULL)) |
||||
+ return 1; |
||||
+ } |
||||
+ parent = wholedisk; |
||||
+ } |
||||
+ |
||||
+ rc = sysfs_init(&cxt, dev, parent); |
||||
+ if (!rc) |
||||
+ rc = sysfs_read_u64(&cxt, "queue/discard_granularity", &dg); |
||||
+ |
||||
+ sysfs_deinit(&cxt); |
||||
+ return rc == 0 && dg > 0; |
||||
+} |
||||
+ |
||||
+ |
||||
+static int uniq_fs_target_cmp( |
||||
+ struct libmnt_table *tb __attribute__((__unused__)), |
||||
+ struct libmnt_fs *a, |
||||
+ struct libmnt_fs *b) |
||||
+{ |
||||
+ return !mnt_fs_streq_target(a, mnt_fs_get_target(b)); |
||||
+} |
||||
+ |
||||
+static int uniq_fs_source_cmp( |
||||
+ struct libmnt_table *tb __attribute__((__unused__)), |
||||
+ struct libmnt_fs *a, |
||||
+ struct libmnt_fs *b) |
||||
+{ |
||||
+ int eq; |
||||
+ |
||||
+ if (mnt_fs_is_pseudofs(a) || mnt_fs_is_netfs(a) || |
||||
+ mnt_fs_is_pseudofs(b) || mnt_fs_is_netfs(b)) |
||||
+ return 1; |
||||
+ |
||||
+ eq = mnt_fs_streq_srcpath(a, mnt_fs_get_srcpath(b)); |
||||
+ if (eq) { |
||||
+ const char *aroot = mnt_fs_get_root(a), |
||||
+ *broot = mnt_fs_get_root(b); |
||||
+ if (!aroot || !broot) |
||||
+ eq = 0; |
||||
+ else if (strcmp(aroot, broot) != 0) |
||||
+ eq = 0; |
||||
+ } |
||||
+ |
||||
+ return !eq; |
||||
+} |
||||
+ |
||||
+/* |
||||
+ * fstrim --all follows "mount -a" return codes: |
||||
+ * |
||||
+ * 0 = all success |
||||
+ * 32 = all failed |
||||
+ * 64 = some failed, some success |
||||
+ */ |
||||
+static int fstrim_all(struct fstrim_range *rangetpl, int verbose) |
||||
+{ |
||||
+ struct libmnt_fs *fs; |
||||
+ struct libmnt_iter *itr; |
||||
+ struct libmnt_table *tab; |
||||
+ struct sysfs_cxt wholedisk = UL_SYSFSCXT_EMPTY; |
||||
+ int cnt = 0, cnt_err = 0; |
||||
+ |
||||
+ mnt_init_debug(0); |
||||
+ |
||||
+ itr = mnt_new_iter(MNT_ITER_BACKWARD); |
||||
+ if (!itr) |
||||
+ err(MOUNT_EX_FAIL, _("failed to initialize libmount iterator")); |
||||
+ |
||||
+ tab = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO); |
||||
+ if (!tab) |
||||
+ err(MOUNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO); |
||||
+ |
||||
+ /* de-duplicate by mountpoints */ |
||||
+ mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp); |
||||
+ |
||||
+ /* de-duplicate by source and root */ |
||||
+ mnt_table_uniq_fs(tab, 0, uniq_fs_source_cmp); |
||||
+ |
||||
+ while (mnt_table_next_fs(tab, itr, &fs) == 0) { |
||||
+ const char *src = mnt_fs_get_srcpath(fs), |
||||
+ *tgt = mnt_fs_get_target(fs); |
||||
+ char *path; |
||||
+ int rc = 1; |
||||
+ |
||||
+ if (!src || !tgt || *src != '/' || |
||||
+ mnt_fs_is_pseudofs(fs) || |
||||
+ mnt_fs_is_netfs(fs)) |
||||
+ continue; |
||||
+ |
||||
+ /* Is it really accessible mountpoint? Not all mountpoints are |
||||
+ * accessible (maybe over mounted by another fylesystem) */ |
||||
+ path = mnt_get_mountpoint(tgt); |
||||
+ if (path && strcmp(path, tgt) == 0) |
||||
+ rc = 0; |
||||
+ free(path); |
||||
+ if (rc) |
||||
+ continue; /* overlaying mount */ |
||||
+ |
||||
+ if (!has_discard(src, &wholedisk)) |
||||
+ continue; |
||||
+ cnt++; |
||||
+ |
||||
+ /* |
||||
+ * We're able to detect that the device supports discard, but |
||||
+ * things also depend on filesystem or device mapping, for |
||||
+ * example vfat or LUKS (by default) does not support FSTRIM. |
||||
+ * |
||||
+ * This is reason why we ignore EOPNOTSUPP and ENOTTY errors |
||||
+ * from discard ioctl. |
||||
+ */ |
||||
+ if (fstrim_filesystem(tgt, rangetpl, verbose) < 0) |
||||
+ cnt_err++; |
||||
+ } |
||||
+ |
||||
+ sysfs_deinit(&wholedisk); |
||||
+ mnt_free_table(tab); |
||||
+ mnt_free_iter(itr); |
||||
+ |
||||
+ if (cnt && cnt == cnt_err) |
||||
+ return MOUNT_EX_FAIL; /* all failed */ |
||||
+ if (cnt && cnt_err) |
||||
+ return MOUNT_EX_SOMEOK; /* some ok */ |
||||
+ |
||||
+ return EXIT_SUCCESS; |
||||
+} |
||||
+ |
||||
static void __attribute__((__noreturn__)) usage(FILE *out) |
||||
{ |
||||
fputs(USAGE_HEADER, out); |
||||
fprintf(out, |
||||
_(" %s [options] <mount point>\n"), program_invocation_short_name); |
||||
+ |
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Discard unused blocks on a mounted filesystem.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
- fputs(_(" -o, --offset <num> offset in bytes to discard from\n" |
||||
- " -l, --length <num> length of bytes to discard from the offset\n" |
||||
- " -m, --minimum <num> minimum extent length to discard\n" |
||||
- " -v, --verbose print number of discarded bytes\n"), out); |
||||
+ fputs(_(" -a, --all trim all mounted filesystems that are supported\n"), out); |
||||
+ fputs(_(" -o, --offset <num> the offset in bytes to start discarding from\n"), out); |
||||
+ fputs(_(" -l, --length <num> the number of bytes to discard\n"), out); |
||||
+ fputs(_(" -m, --minimum <num> the minimum extent length to discard\n"), out); |
||||
+ fputs(_(" -v, --verbose print number of discarded bytes\n"), out); |
||||
+ |
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
fputs(USAGE_VERSION, out); |
||||
@@ -70,12 +275,12 @@ static void __attribute__((__noreturn__) |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
- char *path; |
||||
- int c, fd, verbose = 0; |
||||
+ char *path = NULL; |
||||
+ int c, rc, verbose = 0, all = 0; |
||||
struct fstrim_range range; |
||||
- struct stat sb; |
||||
|
||||
static const struct option longopts[] = { |
||||
+ { "all", 0, 0, 'a' }, |
||||
{ "help", 0, 0, 'h' }, |
||||
{ "version", 0, 0, 'V' }, |
||||
{ "offset", 1, 0, 'o' }, |
||||
@@ -93,8 +298,11 @@ int main(int argc, char **argv) |
||||
memset(&range, 0, sizeof(range)); |
||||
range.len = ULLONG_MAX; |
||||
|
||||
- while ((c = getopt_long(argc, argv, "hVo:l:m:v", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "ahVo:l:m:v", longopts, NULL)) != -1) { |
||||
switch(c) { |
||||
+ case 'a': |
||||
+ all = 1; |
||||
+ break; |
||||
case 'h': |
||||
usage(stdout); |
||||
break; |
||||
@@ -122,38 +330,26 @@ int main(int argc, char **argv) |
||||
} |
||||
} |
||||
|
||||
- if (optind == argc) |
||||
- errx(EXIT_FAILURE, _("no mountpoint specified")); |
||||
- |
||||
- path = argv[optind++]; |
||||
+ if (!all) { |
||||
+ if (optind == argc) |
||||
+ errx(EXIT_FAILURE, _("no mountpoint specified")); |
||||
+ path = argv[optind++]; |
||||
+ } |
||||
|
||||
if (optind != argc) { |
||||
warnx(_("unexpected number of arguments")); |
||||
usage(stderr); |
||||
} |
||||
|
||||
- if (stat(path, &sb) == -1) |
||||
- err(EXIT_FAILURE, _("stat failed %s"), path); |
||||
- if (!S_ISDIR(sb.st_mode)) |
||||
- errx(EXIT_FAILURE, _("%s: not a directory"), path); |
||||
- |
||||
- fd = open(path, O_RDONLY); |
||||
- if (fd < 0) |
||||
- err(EXIT_FAILURE, _("cannot open %s"), path); |
||||
- |
||||
- if (ioctl(fd, FITRIM, &range)) |
||||
- err(EXIT_FAILURE, _("%s: FITRIM ioctl failed"), path); |
||||
- |
||||
- if (verbose) { |
||||
- char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | |
||||
- SIZE_SUFFIX_SPACE, |
||||
- (uint64_t) range.len); |
||||
- /* TRANSLATORS: The standard value here is a very large number. */ |
||||
- printf(_("%s: %s (%" PRIu64 " bytes) trimmed\n"), |
||||
- path, str, |
||||
- (uint64_t) range.len); |
||||
- free(str); |
||||
+ if (all) |
||||
+ rc = fstrim_all(&range, verbose); |
||||
+ else { |
||||
+ rc = fstrim_filesystem(path, &range, verbose); |
||||
+ if (rc == 1) { |
||||
+ warnx(_("%s: the discard operation is not supported"), path); |
||||
+ rc = EXIT_FAILURE; |
||||
+ } |
||||
} |
||||
- close(fd); |
||||
- return EXIT_SUCCESS; |
||||
+ |
||||
+ return rc; |
||||
} |
||||
diff -up util-linux-2.23.2/sys-utils/fstrim.service.in.kzak util-linux-2.23.2/sys-utils/fstrim.service |
||||
--- util-linux-2.23.2/sys-utils/fstrim.service.in.kzak 2015-06-23 12:02:18.505564273 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/fstrim.service.in 2015-06-23 12:02:05.049662802 +0200 |
||||
@@ -0,0 +1,6 @@ |
||||
+[Unit] |
||||
+Description=Discard unused blocks |
||||
+ |
||||
+[Service] |
||||
+Type=oneshot |
||||
+ExecStart=@sbindir@/fstrim -a |
||||
diff -up util-linux-2.23.2/sys-utils/fstrim.timer.kzak util-linux-2.23.2/sys-utils/fstrim.timer |
||||
--- util-linux-2.23.2/sys-utils/fstrim.timer.kzak 2015-06-23 12:02:18.505564273 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/fstrim.timer 2015-06-23 12:02:05.049662802 +0200 |
||||
@@ -0,0 +1,11 @@ |
||||
+[Unit] |
||||
+Description=Discard unused blocks once a week |
||||
+Documentation=man:fstrim |
||||
+ |
||||
+[Timer] |
||||
+OnCalendar=weekly |
||||
+AccuracySec=1h |
||||
+Persistent=true |
||||
+ |
||||
+[Install] |
||||
+WantedBy=multi-user.target |
||||
diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am |
||||
--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak 2015-06-23 11:59:05.803975307 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/Makemodule.am 2015-06-23 12:01:18.682002323 +0200 |
||||
@@ -68,7 +68,18 @@ fsfreeze_SOURCES = sys-utils/fsfreeze.c |
||||
sbin_PROGRAMS += fstrim |
||||
dist_man_MANS += sys-utils/fstrim.8 |
||||
fstrim_SOURCES = sys-utils/fstrim.c |
||||
-fstrim_LDADD = $(LDADD) libcommon.la |
||||
+fstrim_LDADD = $(LDADD) libcommon.la libmount.la |
||||
+fstrim_CFLAGS = $(AM_CFLAGS) -I$(ul_libmount_incdir) |
||||
+ |
||||
+if HAVE_SYSTEMD |
||||
+systemdsystemunit_DATA += \ |
||||
+ sys-utils/fstrim.service \ |
||||
+ sys-utils/fstrim.timer |
||||
+endif |
||||
+ |
||||
+PATHFILES += sys-utils/fstrim.service |
||||
+EXTRA_DIST += sys-utils/fstrim.timer |
||||
+ |
||||
|
||||
sbin_PROGRAMS += blkdiscard |
||||
dist_man_MANS += sys-utils/blkdiscard.8 |
@ -0,0 +1,254 @@
@@ -0,0 +1,254 @@
|
||||
From 4a44a54b3caf77923f0e3f1d5bdf5eda6ef07f62 Mon Sep 17 00:00:00 2001 |
||||
From: Chris MacGregor <chrismacgregor@google.com> |
||||
Date: Thu, 27 Feb 2014 10:40:59 -0800 |
||||
Subject: [PATCH] hwclock: fix possible hang and other |
||||
set_hardware_clock_exact() issues |
||||
|
||||
In sys-utils/hwclock.c, set_hardware_clock_exact() has some problems when the |
||||
process gets pre-empted (for more than 100ms) before reaching the time for |
||||
which it waits: |
||||
|
||||
1. The "continue" statement causes execution to skip the final tdiff |
||||
assignment at the end of the do...while loop, leading to the while condition |
||||
using the wrong value of tdiff, and thus always exiting the loop once |
||||
newhwtime != sethwtime (e.g., after 1 second). This masks bug # 2, below. |
||||
|
||||
2. The previously-existing bug is that because it starts over waiting for the |
||||
desired time whenever two successive calls to gettimeofday() return values > |
||||
100ms apart, the loop will never terminate unless the process holds the CPU |
||||
(without losing it for more than 100ms) for at least 500ms. This can happen |
||||
on a heavily loaded machine or on a virtual machine (or on a heavily loaded |
||||
virtual machine). This has been observed to occur, preventing a machine from |
||||
completing the shutdown or reboot process due to a "hwclock --systohc" call in |
||||
a shutdown script. |
||||
|
||||
The new implementation presented in this patch takes a somewhat different |
||||
approach, intended to accomplish the same goals: |
||||
|
||||
It computes the desired target system time (at which the requested hardware |
||||
clock time will be applied to the hardware clock), and waits for that time to |
||||
arrive. If it misses the time (such as due to being pre-empted for too long), |
||||
it recalculates the target time, and increases the tolerance (how late it can |
||||
be relative to the target time, and still be "close enough". Thus, if all is |
||||
well, the time will be set *very* precisely. On a machine where the hwclock |
||||
process is repeatedly pre-empted, it will set the time as precisely as is |
||||
possible under the conditions present on that particular machine. In any |
||||
case, it will always terminate eventually (and pretty quickly); it will never |
||||
hang forever. |
||||
|
||||
[kzak@redhat.com: - tiny coding style changes] |
||||
|
||||
Signed-off-by: Chris MacGregor <chrismacgregor@google.com> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
sys-utils/hwclock.c | 170 ++++++++++++++++++++++++++++++++++++++++------------ |
||||
1 file changed, 131 insertions(+), 39 deletions(-) |
||||
|
||||
diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c |
||||
index 30660d4..395b5c3 100644 |
||||
--- a/sys-utils/hwclock.c |
||||
+++ b/sys-utils/hwclock.c |
||||
@@ -125,7 +125,7 @@ struct adjtime { |
||||
* We are running in debug mode, wherein we put a lot of information about |
||||
* what we're doing to standard output. |
||||
*/ |
||||
-bool debug; |
||||
+int debug; |
||||
|
||||
/* Workaround for Award 4.50g BIOS bug: keep the year in a file. */ |
||||
bool badyear; |
||||
@@ -526,43 +526,141 @@ set_hardware_clock_exact(const time_t sethwtime, |
||||
const struct timeval refsystime, |
||||
const bool universal, const bool testing) |
||||
{ |
||||
- time_t newhwtime = sethwtime; |
||||
- struct timeval beginsystime, nowsystime; |
||||
- double tdiff; |
||||
- int time_resync = 1; |
||||
- |
||||
/* |
||||
- * Now delay some more until Hardware Clock time newhwtime arrives. |
||||
- * The 0.5 s is because the Hardware Clock always sets to your set |
||||
- * time plus 500 ms (because it is designed to update to the next |
||||
- * second precisely 500 ms after you finish the setting). |
||||
+ * The Hardware Clock can only be set to any integer time plus one |
||||
+ * half second. The integer time is required because there is no |
||||
+ * interface to set or get a fractional second. The additional half |
||||
+ * second is because the Hardware Clock updates to the following |
||||
+ * second precisely 500 ms (not 1 second!) after you release the |
||||
+ * divider reset (after setting the new time) - see description of |
||||
+ * DV2, DV1, DV0 in Register A in the MC146818A data sheet (and note |
||||
+ * that although that document doesn't say so, real-world code seems |
||||
+ * to expect that the SET bit in Register B functions the same way). |
||||
+ * That means that, e.g., when you set the clock to 1:02:03, it |
||||
+ * effectively really sets it to 1:02:03.5, because it will update to |
||||
+ * 1:02:04 only half a second later. Our caller passes the desired |
||||
+ * integer Hardware Clock time in sethwtime, and the corresponding |
||||
+ * system time (which may have a fractional part, and which may or may |
||||
+ * not be the same!) in refsystime. In an ideal situation, we would |
||||
+ * then apply sethwtime to the Hardware Clock at refsystime+500ms, so |
||||
+ * that when the Hardware Clock ticks forward to sethwtime+1s half a |
||||
+ * second later at refsystime+1000ms, everything is in sync. So we |
||||
+ * spin, waiting for gettimeofday() to return a time at or after that |
||||
+ * time (refsystime+500ms) up to a tolerance value, initially 1ms. If |
||||
+ * we miss that time due to being preempted for some other process, |
||||
+ * then we increase the margin a little bit (initially 1ms, doubling |
||||
+ * each time), add 1 second (or more, if needed to get a time that is |
||||
+ * in the future) to both the time for which we are waiting and the |
||||
+ * time that we will apply to the Hardware Clock, and start waiting |
||||
+ * again. |
||||
+ * |
||||
+ * For example, the caller requests that we set the Hardware Clock to |
||||
+ * 1:02:03, with reference time (current system time) = 6:07:08.250. |
||||
+ * We want the Hardware Clock to update to 1:02:04 at 6:07:09.250 on |
||||
+ * the system clock, and the first such update will occur 0.500 |
||||
+ * seconds after we write to the Hardware Clock, so we spin until the |
||||
+ * system clock reads 6:07:08.750. If we get there, great, but let's |
||||
+ * imagine the system is so heavily loaded that our process is |
||||
+ * preempted and by the time we get to run again, the system clock |
||||
+ * reads 6:07:11.990. We now want to wait until the next xx:xx:xx.750 |
||||
+ * time, which is 6:07:12.750 (4.5 seconds after the reference time), |
||||
+ * at which point we will set the Hardware Clock to 1:02:07 (4 seconds |
||||
+ * after the originally requested time). If we do that successfully, |
||||
+ * then at 6:07:13.250 (5 seconds after the reference time), the |
||||
+ * Hardware Clock will update to 1:02:08 (5 seconds after the |
||||
+ * originally requested time), and all is well thereafter. |
||||
*/ |
||||
- do { |
||||
- if (time_resync) { |
||||
- gettimeofday(&beginsystime, NULL); |
||||
- tdiff = time_diff(beginsystime, refsystime); |
||||
- newhwtime = sethwtime + (int)(tdiff + 0.5); |
||||
- if (debug) |
||||
- printf(_ |
||||
- ("Time elapsed since reference time has been %.6f seconds.\n" |
||||
- "Delaying further to reach the new time.\n"), |
||||
- tdiff); |
||||
- time_resync = 0; |
||||
+ |
||||
+ time_t newhwtime = sethwtime; |
||||
+ double target_time_tolerance_secs = 0.001; /* initial value */ |
||||
+ double tolerance_incr_secs = 0.001; /* initial value */ |
||||
+ const double RTC_SET_DELAY_SECS = 0.5; /* 500 ms */ |
||||
+ const struct timeval RTC_SET_DELAY_TV = { 0, RTC_SET_DELAY_SECS * 1E6 }; |
||||
+ |
||||
+ struct timeval targetsystime; |
||||
+ struct timeval nowsystime; |
||||
+ struct timeval prevsystime = refsystime; |
||||
+ double deltavstarget; |
||||
+ |
||||
+ timeradd(&refsystime, &RTC_SET_DELAY_TV, &targetsystime); |
||||
+ |
||||
+ while (1) { |
||||
+ double ticksize; |
||||
+ |
||||
+ /* FOR TESTING ONLY: inject random delays of up to 1000ms */ |
||||
+ if (debug >= 10) { |
||||
+ int usec = random() % 1000000; |
||||
+ printf(_("sleeping ~%d usec\n"), usec); |
||||
+ usleep(usec); |
||||
} |
||||
|
||||
gettimeofday(&nowsystime, NULL); |
||||
- tdiff = time_diff(nowsystime, beginsystime); |
||||
- if (tdiff < 0) { |
||||
- time_resync = 1; /* probably backward time reset */ |
||||
- continue; |
||||
- } |
||||
- if (tdiff > 0.1) { |
||||
- time_resync = 1; /* probably forward time reset */ |
||||
- continue; |
||||
+ deltavstarget = time_diff(nowsystime, targetsystime); |
||||
+ ticksize = time_diff(nowsystime, prevsystime); |
||||
+ prevsystime = nowsystime; |
||||
+ |
||||
+ if (ticksize < 0) { |
||||
+ if (debug) |
||||
+ printf(_("time jumped backward %.6f seconds " |
||||
+ "to %ld.%06d - retargeting\n"), |
||||
+ ticksize, (long)nowsystime.tv_sec, |
||||
+ (int)nowsystime.tv_usec); |
||||
+ /* The retarget is handled at the end of the loop. */ |
||||
+ } else if (deltavstarget < 0) { |
||||
+ /* deltavstarget < 0 if current time < target time */ |
||||
+ if (debug >= 2) |
||||
+ printf(_("%ld.%06d < %ld.%06d (%.6f)\n"), |
||||
+ (long)nowsystime.tv_sec, |
||||
+ (int)nowsystime.tv_usec, |
||||
+ (long)targetsystime.tv_sec, |
||||
+ (int)targetsystime.tv_usec, |
||||
+ deltavstarget); |
||||
+ continue; /* not there yet - keep spinning */ |
||||
+ } else if (deltavstarget <= target_time_tolerance_secs) { |
||||
+ /* Close enough to the target time; done waiting. */ |
||||
+ break; |
||||
+ } else /* (deltavstarget > target_time_tolerance_secs) */ { |
||||
+ /* |
||||
+ * We missed our window. Increase the tolerance and |
||||
+ * aim for the next opportunity. |
||||
+ */ |
||||
+ if (debug) |
||||
+ printf(_("missed it - %ld.%06d is too far " |
||||
+ "past %ld.%06d (%.6f > %.6f)\n"), |
||||
+ (long)nowsystime.tv_sec, |
||||
+ (int)nowsystime.tv_usec, |
||||
+ (long)targetsystime.tv_sec, |
||||
+ (int)targetsystime.tv_usec, |
||||
+ deltavstarget, |
||||
+ target_time_tolerance_secs); |
||||
+ target_time_tolerance_secs += tolerance_incr_secs; |
||||
+ tolerance_incr_secs *= 2; |
||||
} |
||||
- beginsystime = nowsystime; |
||||
- tdiff = time_diff(nowsystime, refsystime); |
||||
- } while (newhwtime == sethwtime + (int)(tdiff + 0.5)); |
||||
+ |
||||
+ /* |
||||
+ * Aim for the same offset (tv_usec) within the second in |
||||
+ * either the current second (if that offset hasn't arrived |
||||
+ * yet), or the next second. |
||||
+ */ |
||||
+ if (nowsystime.tv_usec < targetsystime.tv_usec) |
||||
+ targetsystime.tv_sec = nowsystime.tv_sec; |
||||
+ else |
||||
+ targetsystime.tv_sec = nowsystime.tv_sec + 1; |
||||
+ } |
||||
+ |
||||
+ newhwtime = sethwtime |
||||
+ + (int)(time_diff(nowsystime, refsystime) |
||||
+ - RTC_SET_DELAY_SECS /* don't count this */ |
||||
+ + 0.5 /* for rounding */); |
||||
+ if (debug) |
||||
+ printf(_("%ld.%06d is close enough to %ld.%06d (%.6f < %.6f)\n" |
||||
+ "Set RTC to %ld (%ld + %d; refsystime = %ld.%06d)\n"), |
||||
+ (long)nowsystime.tv_sec, (int)nowsystime.tv_usec, |
||||
+ (long)targetsystime.tv_sec, (int)targetsystime.tv_usec, |
||||
+ deltavstarget, target_time_tolerance_secs, |
||||
+ (long)newhwtime, (long)sethwtime, |
||||
+ (int)(newhwtime - sethwtime), |
||||
+ (long)refsystime.tv_sec, (int)refsystime.tv_usec); |
||||
|
||||
set_hardware_clock(newhwtime, universal, testing); |
||||
} |
||||
@@ -1636,7 +1734,7 @@ int main(int argc, char **argv) |
||||
|
||||
switch (c) { |
||||
case 'D': |
||||
- debug = TRUE; |
||||
+ ++debug; |
||||
break; |
||||
case 'a': |
||||
adjust = TRUE; |
||||
@@ -1953,10 +2051,4 @@ void __attribute__((__noreturn__)) hwaudit_exit(int status) |
||||
* |
||||
* hwclock uses this method, and considers the Hardware Clock to have |
||||
* infinite precision. |
||||
- * |
||||
- * TODO: Enhancements needed: |
||||
- * |
||||
- * - When waiting for whole second boundary in set_hardware_clock_exact, |
||||
- * fail if we miss the goal by more than .1 second, as could happen if we |
||||
- * get pre-empted (by the kernel dispatcher). |
||||
*/ |
||||
-- |
||||
1.9.3 |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
From dd3bc51a539ffdd5c6c6b7d0b20acd1f61bdd337 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Mon, 6 Jan 2014 16:48:13 +0100 |
||||
Subject: [PATCH] lib/path: add path_strdup() |
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
include/path.h | 2 ++ |
||||
lib/path.c | 13 +++++++++++++ |
||||
2 files changed, 15 insertions(+) |
||||
|
||||
diff --git a/include/path.h b/include/path.h |
||||
index 615d284..45da692 100644 |
||||
--- a/include/path.h |
||||
+++ b/include/path.h |
||||
@@ -4,6 +4,8 @@ |
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
|
||||
+extern char *path_strdup(const char *path, ...) |
||||
+ __attribute__ ((__format__ (__printf__, 1, 2))); |
||||
extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...) |
||||
__attribute__ ((__format__ (__printf__, 3, 4))); |
||||
extern void path_read_str(char *result, size_t len, const char *path, ...) |
||||
diff --git a/lib/path.c b/lib/path.c |
||||
index 1f7e258..42d321c 100644 |
||||
--- a/lib/path.c |
||||
+++ b/lib/path.c |
||||
@@ -49,6 +49,19 @@ path_vcreate(const char *path, va_list ap) |
||||
return pathbuf; |
||||
} |
||||
|
||||
+char * |
||||
+path_strdup(const char *path, ...) |
||||
+{ |
||||
+ const char *p; |
||||
+ va_list ap; |
||||
+ |
||||
+ va_start(ap, path); |
||||
+ p = path_vcreate(path, ap); |
||||
+ va_end(ap); |
||||
+ |
||||
+ return p ? strdup(p) : NULL; |
||||
+} |
||||
+ |
||||
static FILE * |
||||
path_vfopen(const char *mode, int exit_on_error, const char *path, va_list ap) |
||||
{ |
||||
-- |
||||
1.8.4.2 |
@ -0,0 +1,240 @@
@@ -0,0 +1,240 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/ext.c.kzak util-linux-2.23.2/libblkid/src/superblocks/ext.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/ext.c.kzak 2013-06-13 09:46:10.422650639 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/ext.c 2014-01-23 10:28:51.175358545 +0100 |
||||
@@ -18,7 +18,6 @@ |
||||
#endif |
||||
#include <time.h> |
||||
|
||||
-#include "linux_version.h" |
||||
#include "superblocks.h" |
||||
|
||||
struct ext2_super_block { |
||||
@@ -132,140 +131,11 @@ struct ext2_super_block { |
||||
#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP |
||||
|
||||
/* |
||||
- * Check to see if a filesystem is in /proc/filesystems. |
||||
- * Returns 1 if found, 0 if not |
||||
- */ |
||||
-static int fs_proc_check(const char *fs_name) |
||||
-{ |
||||
- FILE *f; |
||||
- char buf[80], *cp, *t; |
||||
- |
||||
- f = fopen("/proc/filesystems", "r" UL_CLOEXECSTR); |
||||
- if (!f) |
||||
- return 0; |
||||
- while (!feof(f)) { |
||||
- if (!fgets(buf, sizeof(buf), f)) |
||||
- break; |
||||
- cp = buf; |
||||
- if (!isspace(*cp)) { |
||||
- while (*cp && !isspace(*cp)) |
||||
- cp++; |
||||
- } |
||||
- while (*cp && isspace(*cp)) |
||||
- cp++; |
||||
- if ((t = strchr(cp, '\n')) != NULL) |
||||
- *t = 0; |
||||
- if ((t = strchr(cp, '\t')) != NULL) |
||||
- *t = 0; |
||||
- if ((t = strchr(cp, ' ')) != NULL) |
||||
- *t = 0; |
||||
- if (!strcmp(fs_name, cp)) { |
||||
- fclose(f); |
||||
- return 1; |
||||
- } |
||||
- } |
||||
- fclose(f); |
||||
- return (0); |
||||
-} |
||||
- |
||||
-/* |
||||
- * Check to see if a filesystem is available as a module |
||||
- * Returns 1 if found, 0 if not |
||||
- */ |
||||
-static int check_for_modules(const char *fs_name) |
||||
-{ |
||||
-#ifdef __linux__ |
||||
- struct utsname uts; |
||||
- FILE *f; |
||||
- char buf[1024], *cp; |
||||
- int namesz; |
||||
- |
||||
- if (uname(&uts)) |
||||
- return 0; |
||||
- snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release); |
||||
- |
||||
- f = fopen(buf, "r" UL_CLOEXECSTR); |
||||
- if (!f) |
||||
- return 0; |
||||
- |
||||
- namesz = strlen(fs_name); |
||||
- |
||||
- while (!feof(f)) { |
||||
- if (!fgets(buf, sizeof(buf), f)) |
||||
- break; |
||||
- if ((cp = strchr(buf, ':')) != NULL) |
||||
- *cp = 0; |
||||
- else |
||||
- continue; |
||||
- if ((cp = strrchr(buf, '/')) == NULL) |
||||
- continue; |
||||
- cp++; |
||||
- |
||||
- if (!strncmp(cp, fs_name, namesz) && |
||||
- (!strcmp(cp + namesz, ".ko") || |
||||
- !strcmp(cp + namesz, ".ko.gz"))) { |
||||
- fclose(f); |
||||
- return 1; |
||||
- } |
||||
- } |
||||
- fclose(f); |
||||
-#endif /* __linux__ */ |
||||
- return 0; |
||||
-} |
||||
- |
||||
-/* |
||||
* Starting in 2.6.29, ext4 can be used to support filesystems |
||||
* without a journal. |
||||
*/ |
||||
#define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29) |
||||
|
||||
-static int system_supports_ext2(void) |
||||
-{ |
||||
- static time_t last_check = 0; |
||||
- static int ret = -1; |
||||
- time_t now = time(0); |
||||
- |
||||
- if (ret != -1 || (now - last_check) < 5) |
||||
- return ret; |
||||
- last_check = now; |
||||
- ret = (fs_proc_check("ext2") || check_for_modules("ext2")); |
||||
- return ret; |
||||
-} |
||||
- |
||||
-static int system_supports_ext4(void) |
||||
-{ |
||||
- static time_t last_check = 0; |
||||
- static int ret = -1; |
||||
- time_t now = time(0); |
||||
- |
||||
- if (ret != -1 || (now - last_check) < 5) |
||||
- return ret; |
||||
- last_check = now; |
||||
- ret = (fs_proc_check("ext4") || check_for_modules("ext4")); |
||||
- return ret; |
||||
-} |
||||
- |
||||
-static int system_supports_ext4dev(void) |
||||
-{ |
||||
- static time_t last_check = 0; |
||||
- static int ret = -1; |
||||
- time_t now = time(0); |
||||
- |
||||
- if (ret != -1 || (now - last_check) < 5) |
||||
- return ret; |
||||
- last_check = now; |
||||
- ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev")); |
||||
- return ret; |
||||
-} |
||||
- |
||||
-static int system_supports_ext4_ext2(void) |
||||
-{ |
||||
-#ifdef __linux__ |
||||
- return get_linux_version() >= EXT4_SUPPORTS_EXT2; |
||||
-#else |
||||
- return 0; |
||||
-#endif |
||||
-} |
||||
/* |
||||
* reads superblock and returns: |
||||
* fc = feature_compat |
||||
@@ -355,15 +225,6 @@ static int probe_ext2(blkid_probe pr, |
||||
(fi & EXT2_FEATURE_INCOMPAT_UNSUPPORTED)) |
||||
return -BLKID_ERR_PARAM; |
||||
|
||||
- /* |
||||
- * If ext2 is not present, but ext4 or ext4dev are, then |
||||
- * disclaim we are ext2 |
||||
- */ |
||||
- if (!system_supports_ext2() && |
||||
- (system_supports_ext4() || system_supports_ext4dev()) && |
||||
- system_supports_ext4_ext2()) |
||||
- return -BLKID_ERR_PARAM; |
||||
- |
||||
ext_get_info(pr, 2, es); |
||||
return 0; |
||||
} |
||||
@@ -406,34 +267,9 @@ static int probe_ext4dev(blkid_probe pr, |
||||
if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) |
||||
return -BLKID_ERR_PARAM; |
||||
|
||||
- /* |
||||
- * If the filesystem does not have a journal and ext2 and ext4 |
||||
- * is not present, then force this to be detected as an |
||||
- * ext4dev filesystem. |
||||
- */ |
||||
- if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && |
||||
- !system_supports_ext2() && !system_supports_ext4() && |
||||
- system_supports_ext4dev() && |
||||
- system_supports_ext4_ext2()) |
||||
- goto force_ext4dev; |
||||
- |
||||
- /* |
||||
- * If the filesystem is marked as OK for use by in-development |
||||
- * filesystem code, but ext4dev is not supported, and ext4 is, |
||||
- * then don't call ourselves ext4dev, since we should be |
||||
- * detected as ext4 in that case. |
||||
- * |
||||
- * If the filesystem is marked as in use by production |
||||
- * filesystem, then it can only be used by ext4 and NOT by |
||||
- * ext4dev, so always disclaim we are ext4dev in that case. |
||||
- */ |
||||
- if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { |
||||
- if (!system_supports_ext4dev() && system_supports_ext4()) |
||||
- return -BLKID_ERR_PARAM; |
||||
- } else |
||||
+ if (!(le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS)) |
||||
return -BLKID_ERR_PARAM; |
||||
|
||||
-force_ext4dev: |
||||
ext_get_info(pr, 4, es); |
||||
return 0; |
||||
} |
||||
@@ -452,22 +288,11 @@ static int probe_ext4(blkid_probe pr, |
||||
if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) |
||||
return -BLKID_ERR_PARAM; |
||||
|
||||
- /* |
||||
- * If the filesystem does not have a journal and ext2 is not |
||||
- * present, then force this to be detected as an ext2 |
||||
- * filesystem. |
||||
- */ |
||||
- if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && |
||||
- !system_supports_ext2() && system_supports_ext4() && |
||||
- system_supports_ext4_ext2()) |
||||
- goto force_ext4; |
||||
- |
||||
/* Ext4 has at least one feature which ext3 doesn't understand */ |
||||
if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) && |
||||
!(fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) |
||||
return -BLKID_ERR_PARAM; |
||||
|
||||
-force_ext4: |
||||
/* |
||||
* If the filesystem is a OK for use by in-development |
||||
* filesystem code, and ext4dev is supported or ext4 is not |
||||
@@ -478,10 +303,8 @@ force_ext4: |
||||
* filesystem, then it can only be used by ext4 and NOT by |
||||
* ext4dev. |
||||
*/ |
||||
- if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { |
||||
- if (system_supports_ext4dev() || !system_supports_ext4()) |
||||
- return -BLKID_ERR_PARAM; |
||||
- } |
||||
+ if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) |
||||
+ return -BLKID_ERR_PARAM; |
||||
|
||||
ext_get_info(pr, 4, es); |
||||
return 0; |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/gpt.c.kzak util-linux-2.23.2/libblkid/src/partitions/gpt.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/gpt.c.kzak 2013-07-30 10:39:26.206738239 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/gpt.c 2014-01-23 11:06:17.364011293 +0100 |
||||
@@ -156,13 +156,15 @@ static int last_lba(blkid_probe pr, uint |
||||
* Note that the PMBR detection is optional (enabled by default) and could be |
||||
* disabled by BLKID_PARTS_FOPCE_GPT flag (see also blkid_paertitions_set_flags()). |
||||
*/ |
||||
-static int is_pmbr_valid(blkid_probe pr) |
||||
+static int is_pmbr_valid(blkid_probe pr, int *has) |
||||
{ |
||||
int flags = blkid_partitions_get_flags(pr); |
||||
unsigned char *data; |
||||
struct dos_partition *p; |
||||
int i; |
||||
|
||||
+ if (has) |
||||
+ *has = 0; |
||||
if (flags & BLKID_PARTS_FORCE_GPT) |
||||
goto ok; /* skip PMBR check */ |
||||
|
||||
@@ -182,6 +184,8 @@ static int is_pmbr_valid(blkid_probe pr) |
||||
failed: |
||||
return 0; |
||||
ok: |
||||
+ if (has) |
||||
+ *has = 1; |
||||
return 1; |
||||
} |
||||
|
||||
@@ -305,7 +309,7 @@ static int probe_gpt_pt(blkid_probe pr, |
||||
if (last_lba(pr, &lastlba)) |
||||
goto nothing; |
||||
|
||||
- if (!is_pmbr_valid(pr)) |
||||
+ if (!is_pmbr_valid(pr, NULL)) |
||||
goto nothing; |
||||
|
||||
h = get_gpt_header(pr, &hdr, &e, (lba = GPT_PRIMARY_LBA), lastlba); |
||||
@@ -410,3 +414,39 @@ const struct blkid_idinfo gpt_pt_idinfo |
||||
.magics = BLKID_NONE_MAGIC |
||||
}; |
||||
|
||||
+ |
||||
+ |
||||
+/* probe for *alone* protective MBR */ |
||||
+static int probe_pmbr_pt(blkid_probe pr, |
||||
+ const struct blkid_idmag *mag __attribute__((__unused__))) |
||||
+{ |
||||
+ int has = 0; |
||||
+ struct gpt_entry *e; |
||||
+ uint64_t lastlba = 0; |
||||
+ struct gpt_header hdr; |
||||
+ |
||||
+ if (last_lba(pr, &lastlba)) |
||||
+ goto nothing; |
||||
+ |
||||
+ is_pmbr_valid(pr, &has); |
||||
+ if (!has) |
||||
+ goto nothing; |
||||
+ |
||||
+ if (!get_gpt_header(pr, &hdr, &e, GPT_PRIMARY_LBA, lastlba) && |
||||
+ !get_gpt_header(pr, &hdr, &e, lastlba, lastlba)) |
||||
+ return 0; |
||||
+nothing: |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
+const struct blkid_idinfo pmbr_pt_idinfo = |
||||
+{ |
||||
+ .name = "PMBR", |
||||
+ .probefunc = probe_pmbr_pt, |
||||
+ .magics = |
||||
+ { |
||||
+ { .magic = "\x55\xAA", .len = 2, .sboff = 510 }, |
||||
+ { NULL } |
||||
+ } |
||||
+}; |
||||
+ |
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak 2013-07-30 10:39:26.207738249 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/partitions.c 2014-01-23 11:06:17.364011293 +0100 |
||||
@@ -125,6 +125,7 @@ static const struct blkid_idinfo *idinfo |
||||
&sun_pt_idinfo, |
||||
&dos_pt_idinfo, |
||||
&gpt_pt_idinfo, |
||||
+ &pmbr_pt_idinfo, /* always after GPT */ |
||||
&mac_pt_idinfo, |
||||
&ultrix_pt_idinfo, |
||||
&bsd_pt_idinfo, |
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.h.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.h |
||||
--- util-linux-2.23.2/libblkid/src/partitions/partitions.h.kzak 2013-07-30 10:39:26.208738259 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/partitions.h 2014-01-23 11:06:17.364011293 +0100 |
||||
@@ -59,6 +59,7 @@ extern const struct blkid_idinfo mac_pt_ |
||||
extern const struct blkid_idinfo dos_pt_idinfo; |
||||
extern const struct blkid_idinfo minix_pt_idinfo; |
||||
extern const struct blkid_idinfo gpt_pt_idinfo; |
||||
+extern const struct blkid_idinfo pmbr_pt_idinfo; |
||||
extern const struct blkid_idinfo ultrix_pt_idinfo; |
||||
|
||||
#endif /* BLKID_PARTITIONS_H */ |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/gpt.c.kzak util-linux-2.23.2/libblkid/src/partitions/gpt.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/gpt.c.kzak 2014-09-25 10:36:26.761377688 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/gpt.c 2014-09-25 10:36:56.912665364 +0200 |
||||
@@ -332,7 +332,7 @@ static int probe_gpt_pt(blkid_probe pr, |
||||
|
||||
blkid_probe_use_wiper(pr, lba * blkid_probe_get_size(pr), 8); |
||||
|
||||
- if (blkid_probe_set_magic(pr, lba << 9, |
||||
+ if (blkid_probe_set_magic(pr, blkid_probe_get_sectorsize(pr) * lba, |
||||
sizeof(GPT_HEADER_SIGNATURE_STR) - 1, |
||||
(unsigned char *) GPT_HEADER_SIGNATURE_STR)) |
||||
goto err; |
||||
@@ -345,7 +345,8 @@ static int probe_gpt_pt(blkid_probe pr, |
||||
if (!ls) |
||||
goto err; |
||||
|
||||
- tab = blkid_partlist_new_parttable(ls, "gpt", lba << 9); |
||||
+ tab = blkid_partlist_new_parttable(ls, "gpt", |
||||
+ blkid_probe_get_sectorsize(pr) * lba); |
||||
if (!tab) |
||||
goto err; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/blkidP.h.kzak util-linux-2.23.2/libblkid/src/blkidP.h |
||||
--- util-linux-2.23.2/libblkid/src/blkidP.h.kzak 2013-07-30 10:39:26.205738229 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/blkidP.h 2014-01-23 10:51:10.109593273 +0100 |
||||
@@ -224,9 +224,6 @@ struct blkid_struct_probe |
||||
|
||||
/* private per-probing flags */ |
||||
#define BLKID_PROBE_FL_IGNORE_PT (1 << 1) /* ignore partition table */ |
||||
-#define BLKID_PROBE_FL_IGNORE_BACKUP (1 << 2) /* ignore backup superblocks or PT */ |
||||
- |
||||
-extern int blkid_probe_ignore_backup(blkid_probe pr); |
||||
|
||||
extern blkid_probe blkid_clone_probe(blkid_probe parent); |
||||
extern blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr); |
||||
diff -up util-linux-2.23.2/libblkid/src/probe.c.kzak util-linux-2.23.2/libblkid/src/probe.c |
||||
--- util-linux-2.23.2/libblkid/src/probe.c.kzak 2013-07-30 10:39:26.208738259 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/probe.c 2014-01-23 10:51:10.109593273 +0100 |
||||
@@ -924,7 +924,8 @@ int blkid_do_probe(blkid_probe pr) |
||||
* |
||||
* This function erases the current signature detected by @pr. The @pr has to |
||||
* be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags |
||||
- * has to be enabled. |
||||
+ * has to be enabled (if you want to errase also superblock with broken check |
||||
+ * sums then use BLKID_SUBLKS_BADCSUM too). |
||||
* |
||||
* After successful signature removing the @pr prober will be moved one step |
||||
* back and the next blkid_do_probe() call will again call previously called |
||||
@@ -1125,8 +1126,6 @@ int blkid_do_safeprobe(blkid_probe pr) |
||||
|
||||
blkid_probe_start(pr); |
||||
|
||||
- pr->prob_flags |= BLKID_PROBE_FL_IGNORE_BACKUP; |
||||
- |
||||
for (i = 0; i < BLKID_NCHAINS; i++) { |
||||
struct blkid_chain *chn; |
||||
|
||||
@@ -1764,8 +1763,3 @@ void blkid_probe_use_wiper(blkid_probe p |
||||
blkid_probe_chain_reset_vals(pr, chn); |
||||
} |
||||
} |
||||
- |
||||
-int blkid_probe_ignore_backup(blkid_probe pr) |
||||
-{ |
||||
- return pr && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_BACKUP); |
||||
-} |
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/btrfs.c.kzak util-linux-2.23.2/libblkid/src/superblocks/btrfs.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/btrfs.c.kzak 2013-06-13 09:46:10.421650630 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/btrfs.c 2014-01-23 10:51:10.109593273 +0100 |
||||
@@ -63,11 +63,6 @@ static int probe_btrfs(blkid_probe pr, c |
||||
{ |
||||
struct btrfs_super_block *bfs; |
||||
|
||||
- if (mag->kboff > 64 && blkid_probe_ignore_backup(pr)) { |
||||
- DBG(LOWPROBE, blkid_debug("btrfs: found backup superblock, ignore")); |
||||
- return 1; |
||||
- } |
||||
- |
||||
bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block); |
||||
if (!bfs) |
||||
return -1; |
||||
@@ -92,8 +87,6 @@ const struct blkid_idinfo btrfs_idinfo = |
||||
.magics = |
||||
{ |
||||
{ .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, .kboff = 64 }, |
||||
- { .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, .kboff = 64 * 1024 }, |
||||
- { .magic = "_BHRfS_M", .len = 8, .sboff = 0x40, .kboff = 256 * 1024 * 1024 }, |
||||
{ NULL } |
||||
} |
||||
}; |
@ -0,0 +1,204 @@
@@ -0,0 +1,204 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak 2015-08-11 14:00:27.930573965 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/partitions.c 2015-08-11 14:13:11.213087814 +0200 |
||||
@@ -533,7 +533,7 @@ static int idinfo_probe(blkid_probe pr, |
||||
{ |
||||
const struct blkid_idmag *mag = NULL; |
||||
blkid_loff_t off; |
||||
- int rc = BLKID_PROBE_NONE; /* = nothing detected */ |
||||
+ int rc = BLKID_PROBE_NONE; /* default is nothing */ |
||||
|
||||
if (pr->size <= 0 || (id->minsz && id->minsz > pr->size)) |
||||
goto nothing; /* the device is too small */ |
||||
@@ -564,8 +564,10 @@ static int idinfo_probe(blkid_probe pr, |
||||
DBG(LOWPROBE, blkid_debug("%s: <--- (rc = %d)", id->name, rc)); |
||||
} |
||||
|
||||
-nothing: |
||||
return rc; |
||||
+ |
||||
+nothing: |
||||
+ return BLKID_PROBE_NONE; |
||||
} |
||||
|
||||
/* |
||||
@@ -620,7 +622,7 @@ static int partitions_probe(blkid_probe |
||||
strlen(name) + 1); |
||||
DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (type=%s) [PARTS idx=%d]", |
||||
name, chn->idx)); |
||||
- rc = 0; |
||||
+ rc = BLKID_PROBE_OK; |
||||
break; |
||||
} |
||||
|
||||
@@ -637,10 +639,16 @@ details_only: |
||||
(blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) { |
||||
|
||||
int xrc = blkid_partitions_probe_partition(pr); |
||||
+ |
||||
+ /* partition entry probing is optional, and "not-found" from |
||||
+ * this sub-probing must not to overwrite previous success. */ |
||||
if (xrc < 0) |
||||
- rc = xrc; /* optional, care about errors only */ |
||||
+ rc = xrc; /* always propagate errors */ |
||||
+ else if (rc == BLKID_PROBE_NONE) |
||||
+ rc = xrc; |
||||
} |
||||
|
||||
+ DBG(LOWPROBE, blkid_debug("partitions probe done [rc=%d]", rc)); |
||||
return rc; |
||||
} |
||||
|
||||
@@ -709,7 +717,6 @@ int blkid_partitions_do_subprobe(blkid_p |
||||
|
||||
static int blkid_partitions_probe_partition(blkid_probe pr) |
||||
{ |
||||
- int rc = BLKID_PROBE_NONE; |
||||
blkid_probe disk_pr = NULL; |
||||
blkid_partlist ls; |
||||
blkid_partition par; |
||||
@@ -732,7 +739,9 @@ static int blkid_partitions_probe_partit |
||||
goto nothing; |
||||
|
||||
par = blkid_partlist_devno_to_partition(ls, devno); |
||||
- if (par) { |
||||
+ if (!par) |
||||
+ goto nothing; |
||||
+ else { |
||||
const char *v; |
||||
blkid_parttable tab = blkid_partition_get_table(par); |
||||
dev_t disk = blkid_probe_get_devno(disk_pr); |
||||
@@ -778,9 +787,13 @@ static int blkid_partitions_probe_partit |
||||
blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u", |
||||
major(disk), minor(disk)); |
||||
} |
||||
- rc = BLKID_PROBE_OK; |
||||
+ |
||||
+ DBG(LOWPROBE, blkid_debug("parts: end probing for partition entry [success]")); |
||||
+ return BLKID_PROBE_OK; |
||||
+ |
||||
nothing: |
||||
- return rc; |
||||
+ DBG(LOWPROBE, blkid_debug("parts: end probing for partition entry [nothing]")); |
||||
+ return BLKID_PROBE_NONE; |
||||
} |
||||
|
||||
/* |
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak 2015-07-03 10:35:05.456153560 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c 2015-08-11 14:08:42.572674469 +0200 |
||||
@@ -335,19 +335,24 @@ static int superblocks_probe(blkid_probe |
||||
|
||||
if (!pr || chn->idx < -1) |
||||
return -EINVAL; |
||||
- if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
- goto nothing; |
||||
|
||||
blkid_probe_chain_reset_vals(pr, chn); |
||||
|
||||
DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]", |
||||
chn->idx)); |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return BLKID_PROBE_NONE; |
||||
+ |
||||
if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) |
||||
/* Ignore very very small block devices or regular files (e.g. |
||||
* extended partitions). Note that size of the UBI char devices |
||||
* is 1 byte */ |
||||
- goto nothing; |
||||
+ return BLKID_PROBE_NONE; |
||||
+ |
||||
+ |
||||
+ DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]", |
||||
+ chn->idx)); |
||||
|
||||
i = chn->idx < 0 ? 0 : chn->idx + 1U; |
||||
|
||||
@@ -417,7 +422,7 @@ static int superblocks_probe(blkid_probe |
||||
(unsigned char *) mag->magic); |
||||
if (rc) { |
||||
blkid_probe_chain_reset_vals(pr, chn); |
||||
- DBG(LOWPROBE, blkid_debug("failed to set result -- ingnore")); |
||||
+ DBG(LOWPROBE, blkid_debug("failed to set result -- ignore")); |
||||
continue; |
||||
} |
||||
|
||||
@@ -426,7 +431,6 @@ static int superblocks_probe(blkid_probe |
||||
return BLKID_PROBE_OK; |
||||
} |
||||
|
||||
-nothing: |
||||
DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]", |
||||
rc, chn->idx)); |
||||
return rc; |
||||
@@ -454,13 +458,12 @@ static int superblocks_safeprobe(blkid_p |
||||
int rc; |
||||
|
||||
if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
- return 1; /* nothing */ |
||||
+ return BLKID_PROBE_NONE; |
||||
|
||||
while ((rc = superblocks_probe(pr, chn)) == 0) { |
||||
|
||||
if (blkid_probe_is_tiny(pr) && !count) |
||||
- /* floppy or so -- returns the first result. */ |
||||
- return 0; |
||||
+ return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */ |
||||
|
||||
count++; |
||||
|
||||
@@ -489,7 +492,7 @@ static int superblocks_safeprobe(blkid_p |
||||
return -2; /* error, ambivalent result (more FS) */ |
||||
} |
||||
if (!count) |
||||
- return 1; /* nothing detected */ |
||||
+ return BLKID_PROBE_NONE; |
||||
|
||||
if (idx != -1) { |
||||
/* restore the first result */ |
||||
@@ -506,7 +509,7 @@ static int superblocks_safeprobe(blkid_p |
||||
if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID) |
||||
pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT; |
||||
|
||||
- return 0; |
||||
+ return BLKID_PROBE_OK; |
||||
} |
||||
|
||||
int blkid_probe_set_version(blkid_probe pr, const char *version) |
||||
diff -up util-linux-2.23.2/libblkid/src/topology/topology.c.kzak util-linux-2.23.2/libblkid/src/topology/topology.c |
||||
--- util-linux-2.23.2/libblkid/src/topology/topology.c.kzak 2013-06-13 09:46:10.429650699 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/topology/topology.c 2015-08-11 14:09:35.623361499 +0200 |
||||
@@ -150,7 +150,7 @@ static int topology_probe(blkid_probe pr |
||||
return -1; |
||||
|
||||
if (!S_ISBLK(pr->mode)) |
||||
- return -1; /* nothing, works with block devices only */ |
||||
+ return -EINVAL; /* nothing, works with block devices only */ |
||||
|
||||
if (chn->binary) { |
||||
DBG(LOWPROBE, blkid_debug("initialize topology binary data")); |
||||
@@ -163,7 +163,7 @@ static int topology_probe(blkid_probe pr |
||||
chn->data = calloc(1, |
||||
sizeof(struct blkid_struct_topology)); |
||||
if (!chn->data) |
||||
- return -1; |
||||
+ return -ENOMEM; |
||||
} |
||||
} |
||||
|
||||
@@ -193,12 +193,12 @@ static int topology_probe(blkid_probe pr |
||||
|
||||
DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (type=%s) [TOPOLOGY idx=%d]", |
||||
id->name, chn->idx)); |
||||
- return 0; |
||||
+ return BLKID_PROBE_OK; |
||||
} |
||||
|
||||
DBG(LOWPROBE, blkid_debug("<-- leaving probing loop (failed) [TOPOLOGY idx=%d]", |
||||
chn->idx)); |
||||
- return 1; |
||||
+ return BLKID_PROBE_NONE; |
||||
} |
||||
|
||||
static void topology_free(blkid_probe pr __attribute__((__unused__)), |
@ -0,0 +1,237 @@
@@ -0,0 +1,237 @@
|
||||
diff -up util-linux-2.23.2/fdisks/fdisk.c.kzak util-linux-2.23.2/fdisks/fdisk.c |
||||
--- util-linux-2.23.2/fdisks/fdisk.c.kzak 2015-07-02 12:37:24.465906322 +0200 |
||||
+++ util-linux-2.23.2/fdisks/fdisk.c 2015-07-02 12:37:57.870673753 +0200 |
||||
@@ -34,6 +34,7 @@ |
||||
#include "canonicalize.h" |
||||
#include "strutils.h" |
||||
#include "closestream.h" |
||||
+#include "sysfs.h" |
||||
|
||||
#include "fdisksunlabel.h" |
||||
#include "fdisksgilabel.h" |
||||
diff -up util-linux-2.23.2/include/sysfs.h.kzak util-linux-2.23.2/include/sysfs.h |
||||
--- util-linux-2.23.2/include/sysfs.h.kzak 2015-07-02 12:12:50.408196320 +0200 |
||||
+++ util-linux-2.23.2/include/sysfs.h 2015-07-02 12:13:09.708061372 +0200 |
||||
@@ -74,6 +74,8 @@ extern int sysfs_devno_to_wholedisk(dev_ |
||||
size_t len, dev_t *diskdevno); |
||||
extern int sysfs_devno_is_wholedisk(dev_t devno); |
||||
|
||||
+extern int sysfs_devno_is_lvm_private(dev_t devno); |
||||
+ |
||||
extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, |
||||
int *c, int *t, int *l); |
||||
extern char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt, |
||||
diff -up util-linux-2.23.2/libblkid/src/blkidP.h.kzak util-linux-2.23.2/libblkid/src/blkidP.h |
||||
--- util-linux-2.23.2/libblkid/src/blkidP.h.kzak 2015-07-02 12:18:27.349840375 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/blkidP.h 2015-07-02 12:19:07.797557558 +0200 |
||||
@@ -221,6 +221,7 @@ struct blkid_struct_probe |
||||
#define BLKID_FL_PRIVATE_FD (1 << 1) /* see blkid_new_probe_from_filename() */ |
||||
#define BLKID_FL_TINY_DEV (1 << 2) /* <= 1.47MiB (floppy or so) */ |
||||
#define BLKID_FL_CDROM_DEV (1 << 3) /* is a CD/DVD drive */ |
||||
+#define BLKID_FL_NOSCAN_DEV (1 << 4) /* do not scan this device */ |
||||
|
||||
/* private per-probing flags */ |
||||
#define BLKID_PROBE_FL_IGNORE_PT (1 << 1) /* ignore partition table */ |
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak util-linux-2.23.2/libblkid/src/partitions/partitions.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/partitions.c.kzak 2015-07-02 12:19:11.669530485 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/partitions.c 2015-07-02 12:28:24.166667964 +0200 |
||||
@@ -537,6 +537,8 @@ static int idinfo_probe(blkid_probe pr, |
||||
|
||||
if (pr->size <= 0 || (id->minsz && id->minsz > pr->size)) |
||||
goto nothing; /* the device is too small */ |
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ goto nothing; |
||||
|
||||
rc = blkid_probe_get_idmag(pr, id, &off, &mag); |
||||
if (rc != BLKID_PROBE_OK) |
||||
@@ -576,8 +578,12 @@ static int partitions_probe(blkid_probe |
||||
|
||||
if (!pr || chn->idx < -1) |
||||
return -EINVAL; |
||||
+ |
||||
blkid_probe_chain_reset_vals(pr, chn); |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return BLKID_PROBE_NONE; |
||||
+ |
||||
if (chn->binary) |
||||
partitions_init_data(chn); |
||||
|
||||
@@ -653,6 +659,8 @@ int blkid_partitions_do_subprobe(blkid_p |
||||
|
||||
if (!pr || !parent || !parent->size) |
||||
return -EINVAL; |
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return BLKID_PROBE_NONE; |
||||
|
||||
/* range defined by parent */ |
||||
sz = ((blkid_loff_t) parent->size) << 9; |
||||
@@ -707,6 +715,9 @@ static int blkid_partitions_probe_partit |
||||
blkid_partition par; |
||||
dev_t devno; |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ goto nothing; |
||||
+ |
||||
devno = blkid_probe_get_devno(pr); |
||||
if (!devno) |
||||
goto nothing; |
||||
@@ -779,7 +790,7 @@ nothing: |
||||
int blkid_probe_is_covered_by_pt(blkid_probe pr, |
||||
blkid_loff_t offset, blkid_loff_t size) |
||||
{ |
||||
- blkid_probe prc; |
||||
+ blkid_probe prc = NULL; |
||||
blkid_partlist ls = NULL; |
||||
blkid_loff_t start, end; |
||||
int nparts, i, rc = 0; |
||||
@@ -788,6 +799,9 @@ int blkid_probe_is_covered_by_pt(blkid_p |
||||
"=> checking if off=%jd size=%jd covered by PT", |
||||
offset, size)); |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ goto done; |
||||
+ |
||||
prc = blkid_clone_probe(pr); |
||||
if (!prc) |
||||
goto done; |
||||
diff -up util-linux-2.23.2/libblkid/src/probe.c.kzak util-linux-2.23.2/libblkid/src/probe.c |
||||
--- util-linux-2.23.2/libblkid/src/probe.c.kzak 2015-07-02 12:13:48.823787869 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/probe.c 2015-07-02 12:38:20.110518915 +0200 |
||||
@@ -110,6 +110,7 @@ |
||||
|
||||
#include "blkidP.h" |
||||
#include "all-io.h" |
||||
+#include "sysfs.h" |
||||
|
||||
/* chains */ |
||||
extern const struct blkid_chaindrv superblocks_drv; |
||||
@@ -714,8 +715,13 @@ int blkid_probe_set_device(blkid_probe p |
||||
if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode)) |
||||
pr->flags |= BLKID_FL_TINY_DEV; |
||||
|
||||
+ if (S_ISBLK(sb.st_mode) && sysfs_devno_is_lvm_private(sb.st_rdev)) { |
||||
+ DBG(LOWPROBE, blkid_debug("ignore private LVM device")); |
||||
+ pr->flags |= BLKID_FL_NOSCAN_DEV; |
||||
+ } |
||||
+ |
||||
#ifdef CDROM_GET_CAPABILITY |
||||
- if (S_ISBLK(sb.st_mode) && |
||||
+ else if (S_ISBLK(sb.st_mode) && |
||||
!blkid_probe_is_tiny(pr) && |
||||
blkid_probe_is_wholedisk(pr) && |
||||
ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) |
||||
@@ -892,6 +898,9 @@ int blkid_do_probe(blkid_probe pr) |
||||
if (!pr) |
||||
return -1; |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return 1; |
||||
+ |
||||
do { |
||||
struct blkid_chain *chn = pr->cur_chain; |
||||
|
||||
@@ -1143,6 +1152,8 @@ int blkid_do_safeprobe(blkid_probe pr) |
||||
|
||||
if (!pr) |
||||
return -1; |
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return 1; |
||||
|
||||
blkid_probe_start(pr); |
||||
|
||||
@@ -1197,6 +1208,8 @@ int blkid_do_fullprobe(blkid_probe pr) |
||||
|
||||
if (!pr) |
||||
return -1; |
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return 1; |
||||
|
||||
blkid_probe_start(pr); |
||||
|
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak 2015-07-02 12:29:32.370193121 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c 2015-07-02 12:31:06.897535008 +0200 |
||||
@@ -338,6 +338,9 @@ static int superblocks_probe(blkid_probe |
||||
|
||||
if (!pr || chn->idx < -1) |
||||
return -EINVAL; |
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ goto nothing; |
||||
+ |
||||
blkid_probe_chain_reset_vals(pr, chn); |
||||
|
||||
DBG(LOWPROBE, blkid_debug("--> starting probing loop [SUBLKS idx=%d]", |
||||
@@ -453,6 +456,9 @@ static int superblocks_safeprobe(blkid_p |
||||
int intol = 0; |
||||
int rc; |
||||
|
||||
+ if (pr->flags & BLKID_FL_NOSCAN_DEV) |
||||
+ return 1; /* nothing */ |
||||
+ |
||||
while ((rc = superblocks_probe(pr, chn)) == 0) { |
||||
|
||||
if (blkid_probe_is_tiny(pr) && !count) |
||||
diff -up util-linux-2.23.2/libblkid/src/verify.c.kzak util-linux-2.23.2/libblkid/src/verify.c |
||||
--- util-linux-2.23.2/libblkid/src/verify.c.kzak 2015-07-02 12:15:51.782928121 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/verify.c 2015-07-02 12:16:45.078555470 +0200 |
||||
@@ -112,6 +112,10 @@ blkid_dev blkid_verify(blkid_cache cache |
||||
(unsigned long)diff)); |
||||
#endif |
||||
|
||||
+ if (sysfs_devno_is_lvm_private(st.st_rdev)) { |
||||
+ blkid_free_dev(dev); |
||||
+ return NULL; |
||||
+ } |
||||
if (!cache->probe) { |
||||
cache->probe = blkid_new_probe(); |
||||
if (!cache->probe) { |
||||
diff -up util-linux-2.23.2/lib/sysfs.c.kzak util-linux-2.23.2/lib/sysfs.c |
||||
--- util-linux-2.23.2/lib/sysfs.c.kzak 2015-07-02 12:12:29.193344657 +0200 |
||||
+++ util-linux-2.23.2/lib/sysfs.c 2015-07-02 12:12:13.565453930 +0200 |
||||
@@ -639,6 +639,35 @@ err: |
||||
} |
||||
|
||||
/* |
||||
+ * Returns 1 if the device is private LVM device. |
||||
+ */ |
||||
+int sysfs_devno_is_lvm_private(dev_t devno) |
||||
+{ |
||||
+ struct sysfs_cxt cxt = UL_SYSFSCXT_EMPTY; |
||||
+ char *uuid = NULL; |
||||
+ int rc = 0; |
||||
+ |
||||
+ if (sysfs_init(&cxt, devno, NULL) != 0) |
||||
+ return 0; |
||||
+ |
||||
+ uuid = sysfs_strdup(&cxt, "dm/uuid"); |
||||
+ |
||||
+ /* Private LVM devices use "LVM-<uuid>-<name>" uuid format (important |
||||
+ * is the "LVM" prefix and "-<name>" postfix). |
||||
+ */ |
||||
+ if (uuid && strncmp(uuid, "LVM-", 4) == 0) { |
||||
+ char *p = strrchr(uuid + 4, '-'); |
||||
+ |
||||
+ if (p && *(p + 1)) |
||||
+ rc = 1; |
||||
+ } |
||||
+ |
||||
+ sysfs_deinit(&cxt); |
||||
+ free(uuid); |
||||
+ return rc; |
||||
+} |
||||
+ |
||||
+/* |
||||
* Return 0 or 1, or < 0 in case of error |
||||
*/ |
||||
int sysfs_devno_is_wholedisk(dev_t devno) |
||||
@@ -651,6 +680,9 @@ int sysfs_devno_is_wholedisk(dev_t devno |
||||
return devno == disk; |
||||
} |
||||
|
||||
+ |
||||
+ |
||||
+ |
||||
int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, int *c, int *t, int *l) |
||||
{ |
||||
char buf[PATH_MAX], *hctl; |
@ -0,0 +1,133 @@
@@ -0,0 +1,133 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.c.kzak 2015-06-24 12:58:20.790115492 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.c 2015-06-24 12:57:57.961286166 +0200 |
||||
@@ -49,6 +49,8 @@ |
||||
* |
||||
* @UUID_SUB: subvolume uuid (e.g. btrfs) |
||||
* |
||||
+ * @LOGUUID: external log UUID (e.g. xfs) |
||||
+ * |
||||
* @UUID_RAW: raw UUID from FS superblock |
||||
* |
||||
* @EXT_JOURNAL: external journal UUID |
||||
@@ -113,6 +115,7 @@ static const struct blkid_idinfo *idinfo |
||||
&swsuspend_idinfo, |
||||
&swap_idinfo, |
||||
&xfs_idinfo, |
||||
+ &xfs_log_idinfo, |
||||
&ext4dev_idinfo, |
||||
&ext4_idinfo, |
||||
&ext3_idinfo, |
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak util-linux-2.23.2/libblkid/src/superblocks/superblocks.h |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/superblocks.h.kzak 2015-06-24 12:58:48.533908071 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/superblocks.h 2015-06-24 12:59:00.098821476 +0200 |
||||
@@ -29,6 +29,7 @@ extern const struct blkid_idinfo ext2_id |
||||
extern const struct blkid_idinfo jbd_idinfo; |
||||
extern const struct blkid_idinfo jfs_idinfo; |
||||
extern const struct blkid_idinfo xfs_idinfo; |
||||
+extern const struct blkid_idinfo xfs_log_idinfo; |
||||
extern const struct blkid_idinfo gfs_idinfo; |
||||
extern const struct blkid_idinfo gfs2_idinfo; |
||||
extern const struct blkid_idinfo romfs_idinfo; |
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak util-linux-2.23.2/libblkid/src/superblocks/xfs.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak 2015-06-24 12:39:34.300507071 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/xfs.c 2015-06-24 12:39:45.389427015 +0200 |
||||
@@ -4,6 +4,7 @@ |
||||
* Copyright (C) 2001 by Andreas Dilger |
||||
* Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> |
||||
* Copyright (C) 2008 Karel Zak <kzak@redhat.com> |
||||
+ * Copyright (C) 2013 Eric Sandeen <sandeen@redhat.com> |
||||
* |
||||
* This file may be redistributed under the terms of the |
||||
* GNU Lesser General Public License. |
||||
@@ -187,3 +188,90 @@ const struct blkid_idinfo xfs_idinfo = |
||||
} |
||||
}; |
||||
|
||||
+struct xlog_rec_header { |
||||
+ uint32_t h_magicno; |
||||
+ uint32_t h_dummy1[1]; |
||||
+ uint32_t h_version; |
||||
+ uint32_t h_len; |
||||
+ uint32_t h_dummy2[71]; |
||||
+ uint32_t h_fmt; |
||||
+ unsigned char h_uuid[16]; |
||||
+} __attribute__((packed)); |
||||
+ |
||||
+#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe |
||||
+ |
||||
+/* |
||||
+ * For very small filesystems, the minimum log size |
||||
+ * can be smaller, but that seems vanishingly unlikely |
||||
+ * when used with an external log (which is used for |
||||
+ * performance reasons; tiny conflicts with that goal). |
||||
+ */ |
||||
+#define XFS_MIN_LOG_BYTES (10 * 1024 * 1024) |
||||
+ |
||||
+#define XLOG_FMT_LINUX_LE 1 |
||||
+#define XLOG_FMT_LINUX_BE 2 |
||||
+#define XLOG_FMT_IRIX_BE 3 |
||||
+ |
||||
+#define XLOG_VERSION_1 1 |
||||
+#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ |
||||
+#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) |
||||
+ |
||||
+static int xlog_valid_rec_header(struct xlog_rec_header *rhead) |
||||
+{ |
||||
+ uint32_t hlen; |
||||
+ |
||||
+ if (rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) |
||||
+ return 0; |
||||
+ |
||||
+ if (!rhead->h_version || |
||||
+ (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))) |
||||
+ return 0; |
||||
+ |
||||
+ /* LR body must have data or it wouldn't have been written */ |
||||
+ hlen = be32_to_cpu(rhead->h_len); |
||||
+ if (hlen <= 0 || hlen > INT_MAX) |
||||
+ return 0; |
||||
+ |
||||
+ if (rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_LE) && |
||||
+ rhead->h_fmt != cpu_to_be32(XLOG_FMT_LINUX_BE) && |
||||
+ rhead->h_fmt != cpu_to_be32(XLOG_FMT_IRIX_BE)) |
||||
+ return 0; |
||||
+ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
+/* xlog record header will be in some sector in the first 256k */ |
||||
+static int probe_xfs_log(blkid_probe pr, const struct blkid_idmag *mag) |
||||
+{ |
||||
+ int i; |
||||
+ struct xlog_rec_header *rhead; |
||||
+ unsigned char *buf; |
||||
+ |
||||
+ buf = blkid_probe_get_buffer(pr, 0, 256*1024); |
||||
+ if (!buf) |
||||
+ return errno ? -errno : 1; |
||||
+ |
||||
+ if (memcmp(buf, "XFSB", 4) == 0) |
||||
+ return 1; /* this is regular XFS, ignore */ |
||||
+ |
||||
+ /* check the first 512 512-byte sectors */ |
||||
+ for (i = 0; i < 512; i++) { |
||||
+ rhead = (struct xlog_rec_header *)&buf[i*512]; |
||||
+ |
||||
+ if (xlog_valid_rec_header(rhead)) { |
||||
+ blkid_probe_set_uuid_as(pr, rhead->h_uuid, "LOGUUID"); |
||||
+ return 0; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
+const struct blkid_idinfo xfs_log_idinfo = |
||||
+{ |
||||
+ .name = "xfs_external_log", |
||||
+ .usage = BLKID_USAGE_OTHER, |
||||
+ .probefunc = probe_xfs_log, |
||||
+ .magics = BLKID_NONE_MAGIC, |
||||
+ .minsz = XFS_MIN_LOG_BYTES, |
||||
+}; |
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak util-linux-2.23.2/libblkid/src/superblocks/xfs.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/xfs.c.kzak 2014-09-24 10:59:39.548315524 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/xfs.c 2014-09-24 11:02:55.595186026 +0200 |
||||
@@ -20,20 +20,143 @@ |
||||
#include "superblocks.h" |
||||
|
||||
struct xfs_super_block { |
||||
- unsigned char xs_magic[4]; |
||||
- uint32_t xs_blocksize; |
||||
- uint64_t xs_dblocks; |
||||
- uint64_t xs_rblocks; |
||||
- uint32_t xs_dummy1[2]; |
||||
- unsigned char xs_uuid[16]; |
||||
- uint32_t xs_dummy2[15]; |
||||
- char xs_fname[12]; |
||||
- uint32_t xs_dummy3[2]; |
||||
- uint64_t xs_icount; |
||||
- uint64_t xs_ifree; |
||||
- uint64_t xs_fdblocks; |
||||
+ uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
||||
+ uint32_t sb_blocksize; /* logical block size, bytes */ |
||||
+ uint64_t sb_dblocks; /* number of data blocks */ |
||||
+ uint64_t sb_rblocks; /* number of realtime blocks */ |
||||
+ uint64_t sb_rextents; /* number of realtime extents */ |
||||
+ unsigned char sb_uuid[16]; /* file system unique id */ |
||||
+ uint64_t sb_logstart; /* starting block of log if internal */ |
||||
+ uint64_t sb_rootino; /* root inode number */ |
||||
+ uint64_t sb_rbmino; /* bitmap inode for realtime extents */ |
||||
+ uint64_t sb_rsumino; /* summary inode for rt bitmap */ |
||||
+ uint32_t sb_rextsize; /* realtime extent size, blocks */ |
||||
+ uint32_t sb_agblocks; /* size of an allocation group */ |
||||
+ uint32_t sb_agcount; /* number of allocation groups */ |
||||
+ uint32_t sb_rbmblocks; /* number of rt bitmap blocks */ |
||||
+ uint32_t sb_logblocks; /* number of log blocks */ |
||||
+ |
||||
+ uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */ |
||||
+ uint16_t sb_sectsize; /* volume sector size, bytes */ |
||||
+ uint16_t sb_inodesize; /* inode size, bytes */ |
||||
+ uint16_t sb_inopblock; /* inodes per block */ |
||||
+ char sb_fname[12]; /* file system name */ |
||||
+ uint8_t sb_blocklog; /* log2 of sb_blocksize */ |
||||
+ uint8_t sb_sectlog; /* log2 of sb_sectsize */ |
||||
+ uint8_t sb_inodelog; /* log2 of sb_inodesize */ |
||||
+ uint8_t sb_inopblog; /* log2 of sb_inopblock */ |
||||
+ uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */ |
||||
+ uint8_t sb_rextslog; /* log2 of sb_rextents */ |
||||
+ uint8_t sb_inprogress; /* mkfs is in progress, don't mount */ |
||||
+ uint8_t sb_imax_pct; /* max % of fs for inode space */ |
||||
+ /* statistics */ |
||||
+ uint64_t sb_icount; /* allocated inodes */ |
||||
+ uint64_t sb_ifree; /* free inodes */ |
||||
+ uint64_t sb_fdblocks; /* free data blocks */ |
||||
+ uint64_t sb_frextents; /* free realtime extents */ |
||||
+ |
||||
+ /* this is not all... but enough for libblkid */ |
||||
+ |
||||
} __attribute__((packed)); |
||||
|
||||
+#define XFS_MIN_BLOCKSIZE_LOG 9 /* i.e. 512 bytes */ |
||||
+#define XFS_MAX_BLOCKSIZE_LOG 16 /* i.e. 65536 bytes */ |
||||
+#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG) |
||||
+#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG) |
||||
+#define XFS_MIN_SECTORSIZE_LOG 9 /* i.e. 512 bytes */ |
||||
+#define XFS_MAX_SECTORSIZE_LOG 15 /* i.e. 32768 bytes */ |
||||
+#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG) |
||||
+#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG) |
||||
+ |
||||
+#define XFS_DINODE_MIN_LOG 8 |
||||
+#define XFS_DINODE_MAX_LOG 11 |
||||
+#define XFS_DINODE_MIN_SIZE (1 << XFS_DINODE_MIN_LOG) |
||||
+#define XFS_DINODE_MAX_SIZE (1 << XFS_DINODE_MAX_LOG) |
||||
+ |
||||
+#define XFS_MAX_RTEXTSIZE (1024 * 1024 * 1024) /* 1GB */ |
||||
+#define XFS_DFL_RTEXTSIZE (64 * 1024) /* 64kB */ |
||||
+#define XFS_MIN_RTEXTSIZE (4 * 1024) /* 4kB */ |
||||
+ |
||||
+#define XFS_MIN_AG_BLOCKS 64 |
||||
+#define XFS_MAX_DBLOCKS(s) ((uint64_t)(s)->sb_agcount * (s)->sb_agblocks) |
||||
+#define XFS_MIN_DBLOCKS(s) ((uint64_t)((s)->sb_agcount - 1) * \ |
||||
+ (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) |
||||
+ |
||||
+ |
||||
+static void sb_from_disk(struct xfs_super_block *from, |
||||
+ struct xfs_super_block *to) |
||||
+{ |
||||
+ |
||||
+ to->sb_magicnum = be32_to_cpu(from->sb_magicnum); |
||||
+ to->sb_blocksize = be32_to_cpu(from->sb_blocksize); |
||||
+ to->sb_dblocks = be64_to_cpu(from->sb_dblocks); |
||||
+ to->sb_rblocks = be64_to_cpu(from->sb_rblocks); |
||||
+ to->sb_rextents = be64_to_cpu(from->sb_rextents); |
||||
+ to->sb_logstart = be64_to_cpu(from->sb_logstart); |
||||
+ to->sb_rootino = be64_to_cpu(from->sb_rootino); |
||||
+ to->sb_rbmino = be64_to_cpu(from->sb_rbmino); |
||||
+ to->sb_rsumino = be64_to_cpu(from->sb_rsumino); |
||||
+ to->sb_rextsize = be32_to_cpu(from->sb_rextsize); |
||||
+ to->sb_agblocks = be32_to_cpu(from->sb_agblocks); |
||||
+ to->sb_agcount = be32_to_cpu(from->sb_agcount); |
||||
+ to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); |
||||
+ to->sb_logblocks = be32_to_cpu(from->sb_logblocks); |
||||
+ to->sb_versionnum = be16_to_cpu(from->sb_versionnum); |
||||
+ to->sb_sectsize = be16_to_cpu(from->sb_sectsize); |
||||
+ to->sb_inodesize = be16_to_cpu(from->sb_inodesize); |
||||
+ to->sb_inopblock = be16_to_cpu(from->sb_inopblock); |
||||
+ to->sb_blocklog = from->sb_blocklog; |
||||
+ to->sb_sectlog = from->sb_sectlog; |
||||
+ to->sb_inodelog = from->sb_inodelog; |
||||
+ to->sb_inopblog = from->sb_inopblog; |
||||
+ to->sb_agblklog = from->sb_agblklog; |
||||
+ to->sb_rextslog = from->sb_rextslog; |
||||
+ to->sb_inprogress = from->sb_inprogress; |
||||
+ to->sb_imax_pct = from->sb_imax_pct; |
||||
+ to->sb_icount = be64_to_cpu(from->sb_icount); |
||||
+ to->sb_ifree = be64_to_cpu(from->sb_ifree); |
||||
+ to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); |
||||
+ to->sb_frextents = be64_to_cpu(from->sb_frextents); |
||||
+} |
||||
+ |
||||
+static int xfs_verify_sb(struct xfs_super_block *ondisk) |
||||
+{ |
||||
+ struct xfs_super_block sb, *sbp = &sb; |
||||
+ |
||||
+ /* beXX_to_cpu(), but don't convert UUID and fsname! */ |
||||
+ sb_from_disk(ondisk, sbp); |
||||
+ |
||||
+ /* sanity checks, we don't want to rely on magic string only */ |
||||
+ if (sbp->sb_agcount <= 0 || |
||||
+ sbp->sb_sectsize < XFS_MIN_SECTORSIZE || |
||||
+ sbp->sb_sectsize > XFS_MAX_SECTORSIZE || |
||||
+ sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG || |
||||
+ sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG || |
||||
+ sbp->sb_sectsize != (1 << sbp->sb_sectlog) || |
||||
+ sbp->sb_blocksize < XFS_MIN_BLOCKSIZE || |
||||
+ sbp->sb_blocksize > XFS_MAX_BLOCKSIZE || |
||||
+ sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG || |
||||
+ sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG || |
||||
+ sbp->sb_blocksize != (1 << sbp->sb_blocklog) || |
||||
+ sbp->sb_inodesize < XFS_DINODE_MIN_SIZE || |
||||
+ sbp->sb_inodesize > XFS_DINODE_MAX_SIZE || |
||||
+ sbp->sb_inodelog < XFS_DINODE_MIN_LOG || |
||||
+ sbp->sb_inodelog > XFS_DINODE_MAX_LOG || |
||||
+ sbp->sb_inodesize != (1 << sbp->sb_inodelog) || |
||||
+ (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || |
||||
+ (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || |
||||
+ (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || |
||||
+ (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) || |
||||
+ sbp->sb_dblocks == 0 || |
||||
+ sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) || |
||||
+ sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp)) |
||||
+ return 0; |
||||
+ |
||||
+ /* TODO: version 5 has also checksum CRC32, maybe we can check it too */ |
||||
+ |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag) |
||||
{ |
||||
struct xfs_super_block *xs; |
||||
@@ -42,10 +165,13 @@ static int probe_xfs(blkid_probe pr, con |
||||
if (!xs) |
||||
return errno ? -errno : 1; |
||||
|
||||
- if (strlen(xs->xs_fname)) |
||||
- blkid_probe_set_label(pr, (unsigned char *) xs->xs_fname, |
||||
- sizeof(xs->xs_fname)); |
||||
- blkid_probe_set_uuid(pr, xs->xs_uuid); |
||||
+ if (!xfs_verify_sb(xs)) |
||||
+ return 1; |
||||
+ |
||||
+ if (strlen(xs->sb_fname)) |
||||
+ blkid_probe_set_label(pr, (unsigned char *) xs->sb_fname, |
||||
+ sizeof(xs->sb_fname)); |
||||
+ blkid_probe_set_uuid(pr, xs->sb_uuid); |
||||
return 0; |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/lscpu.c.kzak util-linux-2.23.2/sys-utils/lscpu.c |
||||
--- util-linux-2.23.2/sys-utils/lscpu.c.kzak 2014-09-24 10:27:29.410899893 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/lscpu.c 2014-09-24 10:33:20.960254060 +0200 |
||||
@@ -809,7 +809,7 @@ static inline int is_node_dirent(struct |
||||
return |
||||
d && |
||||
#ifdef _DIRENT_HAVE_D_TYPE |
||||
- d->d_type == DT_DIR && |
||||
+ (d->d_type == DT_DIR || d->d_type == DT_UNKNOWN) && |
||||
#endif |
||||
strncmp(d->d_name, "node", 4) == 0 && |
||||
isdigit_string(d->d_name + 4); |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/lscpu.c.kzak util-linux-2.23.2/sys-utils/lscpu.c |
||||
--- util-linux-2.23.2/sys-utils/lscpu.c.kzak 2013-07-30 10:39:26.342739583 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/lscpu.c 2014-01-14 11:21:51.837599200 +0100 |
||||
@@ -49,6 +49,7 @@ |
||||
/* /sys paths */ |
||||
#define _PATH_SYS_SYSTEM "/sys/devices/system" |
||||
#define _PATH_SYS_CPU _PATH_SYS_SYSTEM "/cpu" |
||||
+#define _PATH_SYS_NODE _PATH_SYS_SYSTEM "/node" |
||||
#define _PATH_PROC_XEN "/proc/xen" |
||||
#define _PATH_PROC_XENCAP _PATH_PROC_XEN "/capabilities" |
||||
#define _PATH_PROC_CPUINFO "/proc/cpuinfo" |
||||
@@ -157,6 +158,7 @@ struct lscpu_desc { |
||||
cpu_set_t *online; /* mask with online CPUs */ |
||||
|
||||
int nnodes; /* number of NUMA modes */ |
||||
+ int *idx2nodenum; /* Support for discontinuous nodes */ |
||||
cpu_set_t **nodemaps; /* array with NUMA nodes */ |
||||
|
||||
/* books -- based on book_siblings (internal kernel map of cpuX's |
||||
@@ -802,25 +804,59 @@ read_cache(struct lscpu_desc *desc, int |
||||
} |
||||
} |
||||
|
||||
+static inline int is_node_dirent(struct dirent *d) |
||||
+{ |
||||
+ return |
||||
+ d && |
||||
+#ifdef _DIRENT_HAVE_D_TYPE |
||||
+ d->d_type == DT_DIR && |
||||
+#endif |
||||
+ strncmp(d->d_name, "node", 4) == 0 && |
||||
+ isdigit_string(d->d_name + 4); |
||||
+} |
||||
+ |
||||
static void |
||||
read_nodes(struct lscpu_desc *desc) |
||||
{ |
||||
- int i; |
||||
+ int i = 0; |
||||
+ DIR *dir; |
||||
+ struct dirent *d; |
||||
+ char *path; |
||||
|
||||
/* number of NUMA node */ |
||||
- while (path_exist(_PATH_SYS_SYSTEM "/node/node%d", desc->nnodes)) |
||||
- desc->nnodes++; |
||||
+ path = path_strdup(_PATH_SYS_NODE); |
||||
+ dir = opendir(path); |
||||
+ free(path); |
||||
+ |
||||
+ while (dir && (d = readdir(dir))) { |
||||
+ if (is_node_dirent(d)) |
||||
+ desc->nnodes++; |
||||
+ } |
||||
|
||||
- if (!desc->nnodes) |
||||
+ if (!desc->nnodes) { |
||||
+ if (dir) |
||||
+ closedir(dir); |
||||
return; |
||||
+ } |
||||
|
||||
desc->nodemaps = xcalloc(desc->nnodes, sizeof(cpu_set_t *)); |
||||
+ desc->idx2nodenum = xmalloc(desc->nnodes * sizeof(int)); |
||||
+ |
||||
+ if (dir) { |
||||
+ rewinddir(dir); |
||||
+ while ((d = readdir(dir)) && i < desc->nnodes) { |
||||
+ if (is_node_dirent(d)) |
||||
+ desc->idx2nodenum[i++] = strtol_or_err(((d->d_name) + 4), |
||||
+ _("Failed to extract the node number")); |
||||
+ } |
||||
+ closedir(dir); |
||||
+ } |
||||
|
||||
/* information about how nodes share different CPUs */ |
||||
for (i = 0; i < desc->nnodes; i++) |
||||
desc->nodemaps[i] = path_read_cpuset(maxcpus, |
||||
_PATH_SYS_SYSTEM "/node/node%d/cpumap", |
||||
- i); |
||||
+ desc->idx2nodenum[i]); |
||||
} |
||||
|
||||
static char * |
||||
@@ -850,7 +886,7 @@ get_cell_data(struct lscpu_desc *desc, i |
||||
case COL_NODE: |
||||
if (cpuset_ary_isset(cpu, desc->nodemaps, |
||||
desc->nnodes, setsize, &idx) == 0) |
||||
- snprintf(buf, bufsz, "%zd", idx); |
||||
+ snprintf(buf, bufsz, "%d", desc->idx2nodenum[idx]); |
||||
break; |
||||
case COL_BOOK: |
||||
if (cpuset_ary_isset(cpu, desc->bookmaps, |
||||
@@ -1250,7 +1286,7 @@ print_summary(struct lscpu_desc *desc, s |
||||
} |
||||
|
||||
for (i = 0; i < desc->nnodes; i++) { |
||||
- snprintf(buf, sizeof(buf), _("NUMA node%d CPU(s):"), i); |
||||
+ snprintf(buf, sizeof(buf), _("NUMA node%d CPU(s):"), desc->idx2nodenum[i]); |
||||
print_cpuset(buf, desc->nodemaps[i], mod->hex); |
||||
} |
||||
} |
@ -0,0 +1,144 @@
@@ -0,0 +1,144 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/lscpu.c.kzak util-linux-2.23.2/sys-utils/lscpu.c |
||||
--- util-linux-2.23.2/sys-utils/lscpu.c.kzak 2014-01-14 14:02:52.228996385 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/lscpu.c 2014-01-14 14:04:08.109795733 +0100 |
||||
@@ -815,6 +815,13 @@ static inline int is_node_dirent(struct |
||||
isdigit_string(d->d_name + 4); |
||||
} |
||||
|
||||
+static int |
||||
+nodecmp(const void *ap, const void *bp) |
||||
+{ |
||||
+ int *a = (int *) ap, *b = (int *) bp; |
||||
+ return *a - *b; |
||||
+} |
||||
+ |
||||
static void |
||||
read_nodes(struct lscpu_desc *desc) |
||||
{ |
||||
@@ -850,6 +857,7 @@ read_nodes(struct lscpu_desc *desc) |
||||
_("Failed to extract the node number")); |
||||
} |
||||
closedir(dir); |
||||
+ qsort(desc->idx2nodenum, desc->nnodes, sizeof(int), nodecmp); |
||||
} |
||||
|
||||
/* information about how nodes share different CPUs */ |
||||
diff -up util-linux-2.23.2/tests/expected/lscpu/lscpu-x86_64-64cpu.kzak util-linux-2.23.2/tests/expected/lscpu/lscpu-x86_64-64cpu |
||||
--- util-linux-2.23.2/tests/expected/lscpu/lscpu-x86_64-64cpu.kzak 2013-06-13 09:46:10.551651742 +0200 |
||||
+++ util-linux-2.23.2/tests/expected/lscpu/lscpu-x86_64-64cpu 2014-01-14 14:04:29.662022613 +0100 |
||||
@@ -4,7 +4,7 @@ On-line CPU(s) list: 0-63 |
||||
Thread(s) per core: 2 |
||||
Core(s) per socket: 8 |
||||
Socket(s): 4 |
||||
-NUMA node(s): 1 |
||||
+NUMA node(s): 3 |
||||
Vendor ID: GenuineIntel |
||||
CPU family: 6 |
||||
Model: 46 |
||||
@@ -18,72 +18,74 @@ L1i cache: 32K |
||||
L2 cache: 256K |
||||
L3 cache: 18432K |
||||
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 |
||||
+NUMA node2 CPU(s): 1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61 |
||||
+NUMA node3 CPU(s): 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63 |
||||
|
||||
# The following is the parsable format, which can be fed to other |
||||
# programs. Each different item in every column has an unique ID |
||||
# starting from zero. |
||||
# CPU,Core,Socket,Node,,L1d,L1i,L2,L3 |
||||
0,0,0,0,,0,0,0,0 |
||||
-1,1,1,,,1,1,1,1 |
||||
+1,1,1,2,,1,1,1,1 |
||||
2,2,2,0,,2,2,2,2 |
||||
-3,3,3,,,3,3,3,3 |
||||
+3,3,3,3,,3,3,3,3 |
||||
4,4,0,0,,4,4,4,0 |
||||
-5,5,1,,,5,5,5,1 |
||||
+5,5,1,2,,5,5,5,1 |
||||
6,6,2,0,,6,6,6,2 |
||||
-7,7,3,,,7,7,7,3 |
||||
+7,7,3,3,,7,7,7,3 |
||||
8,8,0,0,,8,8,8,0 |
||||
-9,9,1,,,9,9,9,1 |
||||
+9,9,1,2,,9,9,9,1 |
||||
10,10,2,0,,10,10,10,2 |
||||
-11,11,3,,,11,11,11,3 |
||||
+11,11,3,3,,11,11,11,3 |
||||
12,12,0,0,,12,12,12,0 |
||||
-13,13,1,,,13,13,13,1 |
||||
+13,13,1,2,,13,13,13,1 |
||||
14,14,2,0,,14,14,14,2 |
||||
-15,15,3,,,15,15,15,3 |
||||
+15,15,3,3,,15,15,15,3 |
||||
16,16,0,0,,16,16,16,0 |
||||
-17,17,1,,,17,17,17,1 |
||||
+17,17,1,2,,17,17,17,1 |
||||
18,18,2,0,,18,18,18,2 |
||||
-19,19,3,,,19,19,19,3 |
||||
+19,19,3,3,,19,19,19,3 |
||||
20,20,0,0,,20,20,20,0 |
||||
-21,21,1,,,21,21,21,1 |
||||
+21,21,1,2,,21,21,21,1 |
||||
22,22,2,0,,22,22,22,2 |
||||
-23,23,3,,,23,23,23,3 |
||||
+23,23,3,3,,23,23,23,3 |
||||
24,24,0,0,,24,24,24,0 |
||||
-25,25,1,,,25,25,25,1 |
||||
+25,25,1,2,,25,25,25,1 |
||||
26,26,2,0,,26,26,26,2 |
||||
-27,27,3,,,27,27,27,3 |
||||
+27,27,3,3,,27,27,27,3 |
||||
28,28,0,0,,28,28,28,0 |
||||
-29,29,1,,,29,29,29,1 |
||||
+29,29,1,2,,29,29,29,1 |
||||
30,30,2,0,,30,30,30,2 |
||||
-31,31,3,,,31,31,31,3 |
||||
+31,31,3,3,,31,31,31,3 |
||||
32,0,0,0,,0,0,0,0 |
||||
-33,1,1,,,1,1,1,1 |
||||
+33,1,1,2,,1,1,1,1 |
||||
34,2,2,0,,2,2,2,2 |
||||
-35,3,3,,,3,3,3,3 |
||||
+35,3,3,3,,3,3,3,3 |
||||
36,4,0,0,,4,4,4,0 |
||||
-37,5,1,,,5,5,5,1 |
||||
+37,5,1,2,,5,5,5,1 |
||||
38,6,2,0,,6,6,6,2 |
||||
-39,7,3,,,7,7,7,3 |
||||
+39,7,3,3,,7,7,7,3 |
||||
40,8,0,0,,8,8,8,0 |
||||
-41,9,1,,,9,9,9,1 |
||||
+41,9,1,2,,9,9,9,1 |
||||
42,10,2,0,,10,10,10,2 |
||||
-43,11,3,,,11,11,11,3 |
||||
+43,11,3,3,,11,11,11,3 |
||||
44,12,0,0,,12,12,12,0 |
||||
-45,13,1,,,13,13,13,1 |
||||
+45,13,1,2,,13,13,13,1 |
||||
46,14,2,0,,14,14,14,2 |
||||
-47,15,3,,,15,15,15,3 |
||||
+47,15,3,3,,15,15,15,3 |
||||
48,16,0,0,,16,16,16,0 |
||||
-49,17,1,,,17,17,17,1 |
||||
+49,17,1,2,,17,17,17,1 |
||||
50,18,2,0,,18,18,18,2 |
||||
-51,19,3,,,19,19,19,3 |
||||
+51,19,3,3,,19,19,19,3 |
||||
52,20,0,0,,20,20,20,0 |
||||
-53,21,1,,,21,21,21,1 |
||||
+53,21,1,2,,21,21,21,1 |
||||
54,22,2,0,,22,22,22,2 |
||||
-55,23,3,,,23,23,23,3 |
||||
+55,23,3,3,,23,23,23,3 |
||||
56,24,0,0,,24,24,24,0 |
||||
-57,25,1,,,25,25,25,1 |
||||
+57,25,1,2,,25,25,25,1 |
||||
58,26,2,0,,26,26,26,2 |
||||
-59,27,3,,,27,27,27,3 |
||||
+59,27,3,3,,27,27,27,3 |
||||
60,28,0,0,,28,28,28,0 |
||||
-61,29,1,,,29,29,29,1 |
||||
+61,29,1,2,,29,29,29,1 |
||||
62,30,2,0,,30,30,30,2 |
||||
-63,31,3,,,31,31,31,3 |
||||
+63,31,3,3,,31,31,31,3 |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/mount.8.kzak util-linux-2.23.2/sys-utils/mount.8 |
||||
--- util-linux-2.23.2/sys-utils/mount.8.kzak 2015-06-24 10:44:54.888929869 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/mount.8 2015-06-24 10:48:10.022436703 +0200 |
||||
@@ -865,9 +865,10 @@ Some of these options are only useful wh |
||||
.I /etc/fstab |
||||
file. |
||||
|
||||
-Some of these options could be enabled or disabled by default |
||||
-in the system kernel. To check the current setting see the options |
||||
-in /proc/mounts. |
||||
+Some of these options could be enabled or disabled by default in the system |
||||
+kernel. To check the current setting see the options in /proc/mounts. Note |
||||
+that filesystems also have per-filesystem specific default mount options (see |
||||
+for example tune2fs -l output for extN filesystems). |
||||
|
||||
The following options apply to any filesystem that is being |
||||
mounted (but not every filesystem actually honors them - e.g., the |
||||
@@ -973,6 +974,9 @@ For more details, see |
||||
.B defaults |
||||
Use default options: |
||||
.BR rw ", " suid ", " dev ", " exec ", " auto ", " nouser ", and " async. |
||||
+ |
||||
+Note that the real set of the all default mount options depends on kernel |
||||
+and filesystem type. See the begin of this section for more details. |
||||
.TP |
||||
.B dev |
||||
Interpret character or block special devices on the filesystem. |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/mount.8.kzak util-linux-2.23.2/sys-utils/mount.8 |
||||
--- util-linux-2.23.2/sys-utils/mount.8.kzak 2014-03-12 12:35:46.532369960 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/mount.8 2014-03-12 12:35:23.041126143 +0100 |
||||
@@ -2598,9 +2598,9 @@ None. |
||||
.TP |
||||
.BR allocsize=size |
||||
Sets the buffered I/O end-of-file preallocation size when |
||||
-doing delayed allocation writeout (default size is 64KiB). |
||||
-Valid values for this option are page size (typically 4KiB) |
||||
-through to 1GiB, inclusive, in power-of-2 increments. |
||||
+doing delayed allocation writeout. Valid values for this |
||||
+option are page size (typically 4KiB) through to 1GiB, |
||||
+inclusive, in power-of-2 increments. |
||||
.sp |
||||
The default behaviour is for dynamic end-of-file |
||||
preallocation size, which uses a set of heuristics to |
@ -0,0 +1,200 @@
@@ -0,0 +1,200 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/swapon.8.kzak util-linux-2.23.2/sys-utils/swapon.8 |
||||
--- util-linux-2.23.2/sys-utils/swapon.8.kzak 2013-06-13 09:46:10.544651682 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/swapon.8 2014-09-24 10:57:45.855230767 +0200 |
||||
@@ -112,15 +112,25 @@ All devices marked as ``swap'' in |
||||
are made available, except for those with the ``noauto'' option. |
||||
Devices that are already being used as swap are silently skipped. |
||||
.TP |
||||
-.B "\-d, \-\-discard" |
||||
-Discard freed swap pages before they are reused, if the swap |
||||
-device supports the discard or trim operation. This may improve |
||||
-performance on some Solid State Devices, but often it does not. |
||||
+.B "\-d, \-\-discard\fR [=\fIpolicy\fR]" |
||||
+Enable swap discards, if the swap backing device supports the discard or |
||||
+trim operation. This may improve performance on some Solid State Devices, |
||||
+but often it does not. The option allows one to select between two |
||||
+available swap discard policies: |
||||
+.BI \-\-discard=once |
||||
+to perform a single-time discard operation for the whole swap area at swapon; |
||||
+or |
||||
+.BI \-\-discard=pages |
||||
+to discard freed swap pages before they are reused, while swapping. |
||||
+If no policy is selected, the default behavior is to enable both discard types. |
||||
The |
||||
.I /etc/fstab |
||||
-mount option |
||||
-.BI discard |
||||
-may be also used to enable discard flag. |
||||
+mount options |
||||
+.BI discard, |
||||
+.BI discard=once, |
||||
+or |
||||
+.BI discard=pages |
||||
+may be also used to enable discard flags. |
||||
.TP |
||||
.B "\-e, \-\-ifexists" |
||||
Silently skip devices that do not exist. |
||||
diff -up util-linux-2.23.2/sys-utils/swapon.c.kzak util-linux-2.23.2/sys-utils/swapon.c |
||||
--- util-linux-2.23.2/sys-utils/swapon.c.kzak 2013-07-30 10:39:26.348739643 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/swapon.c 2014-09-24 10:57:45.855230767 +0200 |
||||
@@ -34,9 +34,20 @@ |
||||
#endif |
||||
|
||||
#ifndef SWAP_FLAG_DISCARD |
||||
-# define SWAP_FLAG_DISCARD 0x10000 /* discard swap cluster after use */ |
||||
+# define SWAP_FLAG_DISCARD 0x10000 /* enable discard for swap */ |
||||
#endif |
||||
|
||||
+#ifndef SWAP_FLAG_DISCARD_ONCE |
||||
+# define SWAP_FLAG_DISCARD_ONCE 0x20000 /* discard swap area at swapon-time */ |
||||
+#endif |
||||
+ |
||||
+#ifndef SWAP_FLAG_DISCARD_PAGES |
||||
+# define SWAP_FLAG_DISCARD_PAGES 0x40000 /* discard page-clusters after use */ |
||||
+#endif |
||||
+ |
||||
+#define SWAP_FLAGS_DISCARD_VALID (SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \ |
||||
+ SWAP_FLAG_DISCARD_PAGES) |
||||
+ |
||||
#ifndef SWAP_FLAG_PREFER |
||||
# define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ |
||||
#endif |
||||
@@ -70,7 +81,7 @@ enum { |
||||
|
||||
static int all; |
||||
static int priority = -1; /* non-prioritized swap by default */ |
||||
-static int discard; |
||||
+static int discard; /* don't send swap discards by default */ |
||||
|
||||
/* If true, don't complain if the device/file doesn't exist */ |
||||
static int ifexists; |
||||
@@ -567,8 +578,22 @@ static int do_swapon(const char *orig_sp |
||||
<< SWAP_FLAG_PRIO_SHIFT); |
||||
} |
||||
#endif |
||||
- if (fl_discard) |
||||
- flags |= SWAP_FLAG_DISCARD; |
||||
+ /* |
||||
+ * Validate the discard flags passed and set them |
||||
+ * accordingly before calling sys_swapon. |
||||
+ */ |
||||
+ if (fl_discard && !(fl_discard & ~SWAP_FLAGS_DISCARD_VALID)) { |
||||
+ /* |
||||
+ * If we get here with both discard policy flags set, |
||||
+ * we just need to tell the kernel to enable discards |
||||
+ * and it will do correctly, just as we expect. |
||||
+ */ |
||||
+ if ((fl_discard & SWAP_FLAG_DISCARD_ONCE) && |
||||
+ (fl_discard & SWAP_FLAG_DISCARD_PAGES)) |
||||
+ flags |= SWAP_FLAG_DISCARD; |
||||
+ else |
||||
+ flags |= fl_discard; |
||||
+ } |
||||
|
||||
status = swapon(special, flags); |
||||
if (status < 0) |
||||
@@ -608,12 +633,22 @@ static int swapon_all(void) |
||||
while (mnt_table_find_next_fs(tb, itr, match_swap, NULL, &fs) == 0) { |
||||
/* defaults */ |
||||
int pri = priority, dsc = discard, nofail = ifexists; |
||||
- char *p, *src; |
||||
+ char *p, *src, *dscarg; |
||||
|
||||
if (mnt_fs_get_option(fs, "noauto", NULL, NULL) == 0) |
||||
continue; |
||||
- if (mnt_fs_get_option(fs, "discard", NULL, NULL) == 0) |
||||
- dsc = 1; |
||||
+ if (mnt_fs_get_option(fs, "discard", &dscarg, NULL) == 0) { |
||||
+ dsc |= SWAP_FLAG_DISCARD; |
||||
+ if (dscarg) { |
||||
+ /* only single-time discards are wanted */ |
||||
+ if (strcmp(dscarg, "once") == 0) |
||||
+ dsc |= SWAP_FLAG_DISCARD_ONCE; |
||||
+ |
||||
+ /* do discard for every released swap page */ |
||||
+ if (strcmp(dscarg, "pages") == 0) |
||||
+ dsc |= SWAP_FLAG_DISCARD_PAGES; |
||||
+ } |
||||
+ } |
||||
if (mnt_fs_get_option(fs, "nofail", NULL, NULL) == 0) |
||||
nofail = 1; |
||||
if (mnt_fs_get_option(fs, "pri", &p, NULL) == 0 && p) |
||||
@@ -643,17 +678,17 @@ static void __attribute__ ((__noreturn__ |
||||
fprintf(out, _(" %s [options] [<spec>]\n"), program_invocation_short_name); |
||||
|
||||
fputs(USAGE_OPTIONS, out); |
||||
- fputs(_(" -a, --all enable all swaps from /etc/fstab\n" |
||||
- " -d, --discard discard freed pages before they are reused\n" |
||||
- " -e, --ifexists silently skip devices that do not exist\n" |
||||
- " -f, --fixpgsz reinitialize the swap space if necessary\n" |
||||
- " -p, --priority <prio> specify the priority of the swap device\n" |
||||
- " -s, --summary display summary about used swap devices\n" |
||||
- " --show[=<columns>] display summary in definable table\n" |
||||
- " --noheadings don't print headings, use with --show\n" |
||||
- " --raw use the raw output format, use with --show\n" |
||||
- " --bytes display swap size in bytes in --show output\n" |
||||
- " -v, --verbose verbose mode\n"), out); |
||||
+ fputs(_(" -a, --all enable all swaps from /etc/fstab\n" |
||||
+ " -d, --discard[=<policy>] enable swap discards, if supported by device\n" |
||||
+ " -e, --ifexists silently skip devices that do not exist\n" |
||||
+ " -f, --fixpgsz reinitialize the swap space if necessary\n" |
||||
+ " -p, --priority <prio> specify the priority of the swap device\n" |
||||
+ " -s, --summary display summary about used swap devices\n" |
||||
+ " --show[=<columns>] display summary in definable table\n" |
||||
+ " --noheadings don't print headings, use with --show\n" |
||||
+ " --raw use the raw output format, use with --show\n" |
||||
+ " --bytes display swap size in bytes in --show output\n" |
||||
+ " -v, --verbose verbose mode\n"), out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
@@ -669,6 +704,11 @@ static void __attribute__ ((__noreturn__ |
||||
" <device> name of device to be used\n" |
||||
" <file> name of file to be used\n"), out); |
||||
|
||||
+ fputs(_("\nAvailable discard policy types (for --discard):\n" |
||||
+ " once : only single-time area discards are issued. (swapon)\n" |
||||
+ " pages : discard freed pages before they are reused.\n" |
||||
+ " * if no policy is selected both discard types are enabled. (default)\n"), out); |
||||
+ |
||||
fputs(_("\nAvailable columns (for --show):\n"), out); |
||||
for (i = 0; i < NCOLS; i++) |
||||
fprintf(out, " %4s %s\n", infos[i].name, _(infos[i].help)); |
||||
@@ -693,7 +733,7 @@ int main(int argc, char *argv[]) |
||||
|
||||
static const struct option long_opts[] = { |
||||
{ "priority", 1, 0, 'p' }, |
||||
- { "discard", 0, 0, 'd' }, |
||||
+ { "discard", 2, 0, 'd' }, |
||||
{ "ifexists", 0, 0, 'e' }, |
||||
{ "summary", 0, 0, 's' }, |
||||
{ "fixpgsz", 0, 0, 'f' }, |
||||
@@ -716,7 +756,7 @@ int main(int argc, char *argv[]) |
||||
mnt_init_debug(0); |
||||
mntcache = mnt_new_cache(); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "ahdefp:svVL:U:", |
||||
+ while ((c = getopt_long(argc, argv, "ahd::efp:svVL:U:", |
||||
long_opts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'a': /* all */ |
||||
@@ -736,7 +776,18 @@ int main(int argc, char *argv[]) |
||||
add_uuid(optarg); |
||||
break; |
||||
case 'd': |
||||
- discard = 1; |
||||
+ discard |= SWAP_FLAG_DISCARD; |
||||
+ if (optarg) { |
||||
+ if (*optarg == '=') |
||||
+ optarg++; |
||||
+ |
||||
+ if (strcmp(optarg, "once") == 0) |
||||
+ discard |= SWAP_FLAG_DISCARD_ONCE; |
||||
+ else if (strcmp(optarg, "pages") == 0) |
||||
+ discard |= SWAP_FLAG_DISCARD_PAGES; |
||||
+ else |
||||
+ errx(EXIT_FAILURE, _("unsupported discard policy: %s"), optarg); |
||||
+ } |
||||
break; |
||||
case 'e': /* ifexists */ |
||||
ifexists = 1; |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
From ab0e0fa7a45bccf8304edcb2a904f30a4f3a48b1 Mon Sep 17 00:00:00 2001 |
||||
From: Rik van Riel <riel@redhat.com> |
||||
Date: Fri, 6 Dec 2013 16:07:54 -0500 |
||||
Subject: [PATCH] taskset: fix PERMISSIONS section of taskset man page |
||||
|
||||
A user is always allowed to change the CPU affinity of his or her |
||||
own processes. CAP_SYS_NICE is only required to change the affinity |
||||
of another user's process. |
||||
|
||||
Signed-off-by: Rik van Riel <riel@redhat.com> |
||||
Reported-by: Joe Mario <jmario@redhat.com> |
||||
--- |
||||
schedutils/taskset.1 | 5 +++-- |
||||
1 file changed, 3 insertions(+), 2 deletions(-) |
||||
|
||||
diff --git a/schedutils/taskset.1 b/schedutils/taskset.1 |
||||
index ade202b..fb5738c 100644 |
||||
--- a/schedutils/taskset.1 |
||||
+++ b/schedutils/taskset.1 |
||||
@@ -102,10 +102,11 @@ Or set it: |
||||
.B taskset \-p |
||||
.I mask pid |
||||
.SH PERMISSIONS |
||||
+A user can change the CPU affinity of a process belonging to the same user. |
||||
A user must possess |
||||
.B CAP_SYS_NICE |
||||
-to change the CPU affinity of a process. Any user can retrieve the affinity |
||||
-mask. |
||||
+to change the CPU affinity of a process belonging to another user. |
||||
+A user can retrieve the affinity mask of any process. |
||||
.SH AUTHOR |
||||
Written by Robert M. Love. |
||||
.SH COPYRIGHT |
||||
-- |
||||
1.8.4.2 |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/uuidd.service.in.kzak util-linux-2.23.2/misc-utils/uuidd.service.in |
||||
--- util-linux-2.23.2/misc-utils/uuidd.service.in.kzak 2013-02-27 17:46:29.903020913 +0100 |
||||
+++ util-linux-2.23.2/misc-utils/uuidd.service.in 2015-04-20 11:31:44.614013049 +0200 |
||||
@@ -3,7 +3,7 @@ Description=Daemon for generating UUIDs |
||||
Requires=uuidd.socket |
||||
|
||||
[Service] |
||||
-ExecStart=@usrsbin_execdir@/uuidd --socket-activation --timeout 60 |
||||
+ExecStart=@usrsbin_execdir@/uuidd --socket-activation |
||||
Restart=no |
||||
User=uuidd |
||||
Group=uuidd |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/wipefs.8.kzak util-linux-2.23.2/misc-utils/wipefs.8 |
||||
--- util-linux-2.23.2/misc-utils/wipefs.8.kzak 2013-07-30 10:39:26.232738496 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/wipefs.8 2014-01-23 11:07:54.390022299 +0100 |
||||
@@ -23,6 +23,9 @@ does not erase the filesystem itself nor |
||||
When used without options \fB-a\fR or \fB-o\fR, it lists all visible filesystems |
||||
and the offsets of their basic signatures. |
||||
|
||||
+.B wipefs |
||||
+calls BLKRRPART ioctl when erase partition table to inform kernel about the change. |
||||
+ |
||||
Note that some filesystems or some partition tables store more magic strings on |
||||
the devices. The |
||||
.B wipefs |
||||
diff -up util-linux-2.23.2/misc-utils/wipefs.c.kzak util-linux-2.23.2/misc-utils/wipefs.c |
||||
--- util-linux-2.23.2/misc-utils/wipefs.c.kzak 2013-07-30 10:39:26.232738496 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/wipefs.c 2014-01-23 11:12:26.786860550 +0100 |
||||
@@ -40,21 +40,24 @@ |
||||
#include "c.h" |
||||
#include "closestream.h" |
||||
#include "optutils.h" |
||||
+#include "blkdev.h" |
||||
|
||||
struct wipe_desc { |
||||
loff_t offset; /* magic string offset */ |
||||
size_t len; /* length of magic string */ |
||||
unsigned char *magic; /* magic string */ |
||||
|
||||
- int zap; /* zap this offset? */ |
||||
char *usage; /* raid, filesystem, ... */ |
||||
char *type; /* FS type */ |
||||
char *label; /* FS label */ |
||||
char *uuid; /* FS uuid */ |
||||
|
||||
- int on_disk; |
||||
- |
||||
struct wipe_desc *next; |
||||
+ |
||||
+ unsigned int zap : 1, |
||||
+ on_disk : 1, |
||||
+ is_parttable : 1; |
||||
+ |
||||
}; |
||||
|
||||
enum { |
||||
@@ -72,7 +75,7 @@ print_pretty(struct wipe_desc *wp, int l |
||||
printf("----------------------------------------------------------------\n"); |
||||
} |
||||
|
||||
- printf("0x%-17jx %s [%s]", wp->offset, wp->type, wp->usage); |
||||
+ printf("0x%-17jx %s [%s]", wp->offset, wp->type, _(wp->usage)); |
||||
|
||||
if (wp->label && *wp->label) |
||||
printf("\n%27s %s", "LABEL:", wp->label); |
||||
@@ -141,7 +144,7 @@ add_offset(struct wipe_desc *wp0, loff_t |
||||
wp = xcalloc(1, sizeof(struct wipe_desc)); |
||||
wp->offset = offset; |
||||
wp->next = wp0; |
||||
- wp->zap = zap; |
||||
+ wp->zap = zap ? 1 : 0; |
||||
return wp; |
||||
} |
||||
|
||||
@@ -164,7 +167,7 @@ get_desc_for_probe(struct wipe_desc *wp, |
||||
const char *off, *type, *mag, *p, *usage = NULL; |
||||
size_t len; |
||||
loff_t offset; |
||||
- int rc; |
||||
+ int rc, ispt = 0; |
||||
|
||||
/* superblocks */ |
||||
if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0) { |
||||
@@ -181,7 +184,8 @@ get_desc_for_probe(struct wipe_desc *wp, |
||||
rc = blkid_probe_lookup_value(pr, "PTMAGIC", &mag, &len); |
||||
if (rc) |
||||
return wp; |
||||
- usage = "partition table"; |
||||
+ usage = N_("partition table"); |
||||
+ ispt = 1; |
||||
} else |
||||
return wp; |
||||
|
||||
@@ -199,6 +203,7 @@ get_desc_for_probe(struct wipe_desc *wp, |
||||
|
||||
wp->type = xstrdup(type); |
||||
wp->on_disk = 1; |
||||
+ wp->is_parttable = ispt ? 1 : 0; |
||||
|
||||
wp->magic = xmalloc(len); |
||||
memcpy(wp->magic, mag, len); |
||||
@@ -309,10 +314,25 @@ static void do_wipe_real(blkid_probe pr, |
||||
putchar('\n'); |
||||
} |
||||
|
||||
+ |
||||
+static void rereadpt(int fd, const char *devname) |
||||
+{ |
||||
+#ifdef BLKRRPART |
||||
+ struct stat st; |
||||
+ |
||||
+ if (fstat(fd, &st) || !S_ISBLK(st.st_mode)) |
||||
+ return; |
||||
+ |
||||
+ errno = 0; |
||||
+ ioctl(fd, BLKRRPART); |
||||
+ printf(_("%s: calling ioclt to re-read partition table: %m\n"), devname); |
||||
+#endif |
||||
+} |
||||
+ |
||||
static struct wipe_desc * |
||||
do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet, int force) |
||||
{ |
||||
- int flags; |
||||
+ int flags, reread = 0; |
||||
blkid_probe pr; |
||||
struct wipe_desc *w, *wp0; |
||||
int zap = all ? 1 : wp->zap; |
||||
@@ -345,8 +365,11 @@ do_wipe(struct wipe_desc *wp, const char |
||||
if (!wp->on_disk) |
||||
continue; |
||||
|
||||
- if (zap) |
||||
+ if (zap) { |
||||
do_wipe_real(pr, devname, wp, noact, quiet); |
||||
+ if (wp->is_parttable) |
||||
+ reread = 1; |
||||
+ } |
||||
} |
||||
|
||||
for (w = wp0; w != NULL; w = w->next) { |
||||
@@ -355,6 +378,10 @@ do_wipe(struct wipe_desc *wp, const char |
||||
} |
||||
|
||||
fsync(blkid_probe_get_fd(pr)); |
||||
+ |
||||
+ if (reread) |
||||
+ rereadpt(blkid_probe_get_fd(pr), devname); |
||||
+ |
||||
close(blkid_probe_get_fd(pr)); |
||||
blkid_free_probe(pr); |
||||
free_wipe(wp0); |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/wipefs.8.kzak util-linux-2.23.2/misc-utils/wipefs.8 |
||||
--- util-linux-2.23.2/misc-utils/wipefs.8.kzak 2014-09-24 10:41:31.061930168 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/wipefs.8 2014-09-24 10:46:30.142783728 +0200 |
||||
@@ -37,6 +37,11 @@ table will still be visible by another m |
||||
When used with option \fB-a\fR, all magic strings that are visible for libblkid are |
||||
erased. |
||||
|
||||
+Note that by default |
||||
+.B wipefs |
||||
+does not erase nested partition tables on non-whole disk devices. The option |
||||
+\-\-force is required. |
||||
+ |
||||
.SH OPTIONS |
||||
.TP |
||||
.BR \-a , " \-\-all" |
||||
diff -up util-linux-2.23.2/misc-utils/wipefs.c.kzak util-linux-2.23.2/misc-utils/wipefs.c |
||||
--- util-linux-2.23.2/misc-utils/wipefs.c.kzak 2014-09-24 10:41:31.061930168 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/wipefs.c 2014-09-24 10:50:07.728859738 +0200 |
||||
@@ -332,7 +332,7 @@ static void rereadpt(int fd, const char |
||||
static struct wipe_desc * |
||||
do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all, int quiet, int force) |
||||
{ |
||||
- int flags, reread = 0; |
||||
+ int flags, reread = 0, need_force = 0; |
||||
blkid_probe pr; |
||||
struct wipe_desc *w, *wp0; |
||||
int zap = all ? 1 : wp->zap; |
||||
@@ -365,6 +365,15 @@ do_wipe(struct wipe_desc *wp, const char |
||||
if (!wp->on_disk) |
||||
continue; |
||||
|
||||
+ if (!force |
||||
+ && wp->is_parttable |
||||
+ && !blkid_probe_is_wholedisk(pr)) { |
||||
+ warnx(_("%s: ignore nested \"%s\" partition " |
||||
+ "table on non-whole disk device."), devname, wp->type); |
||||
+ need_force = 1; |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
if (zap) { |
||||
do_wipe_real(pr, devname, wp, noact, quiet); |
||||
if (wp->is_parttable) |
||||
@@ -377,6 +386,9 @@ do_wipe(struct wipe_desc *wp, const char |
||||
warnx(_("%s: offset 0x%jx not found"), devname, w->offset); |
||||
} |
||||
|
||||
+ if (need_force) |
||||
+ warnx(_("Use the --force option to force erase.")); |
||||
+ |
||||
fsync(blkid_probe_get_fd(pr)); |
||||
|
||||
if (reread) |
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/blkdiscard.8.kzak util-linux-2.23.2/sys-utils/blkdiscard.8 |
||||
--- util-linux-2.23.2/sys-utils/blkdiscard.8.kzak 2013-06-13 09:46:10.532651579 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/blkdiscard.8 2014-10-27 10:03:13.650011708 +0100 |
||||
@@ -1,5 +1,5 @@ |
||||
.\" -*- nroff -*- |
||||
-.TH BLKDISCARD 8 "October 2012" "util-linux" "System Administration" |
||||
+.TH BLKDISCARD 8 "July 2014" "util-linux" "System Administration" |
||||
.SH NAME |
||||
blkdiscard \- discard sectors on a device |
||||
.SH SYNOPSIS |
||||
@@ -15,7 +15,7 @@ blkdiscard \- discard sectors on a devic |
||||
.B blkdiscard |
||||
is used to discard device sectors. This is useful for solid-state |
||||
drivers (SSDs) and thinly-provisioned storage. Unlike |
||||
-.BR fstrim (8) |
||||
+.BR fstrim (8) , |
||||
this command is used directly on the block device. |
||||
.PP |
||||
By default, |
||||
@@ -33,32 +33,44 @@ The |
||||
.I offset |
||||
and |
||||
.I length |
||||
-arguments may be followed by the multiplicative suffixes KiB=1024, |
||||
-MiB=1024*1024, and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is |
||||
+arguments may be followed by the multiplicative suffixes KiB (=1024), |
||||
+MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is |
||||
optional, e.g., "K" has the same meaning as "KiB") or the suffixes |
||||
-KB=1000, MB=1000*1000, and so on for GB, TB, PB, EB, ZB and YB. |
||||
-.IP "\fB\-h, \-\-help\fP" |
||||
-Print help and exit. |
||||
-.IP "\fB\-o, \-\-offset\fP \fIoffset\fP" |
||||
-Byte offset in the device from which to discard. Provided value will be |
||||
-aligned to the device sector size. Default value is zero. |
||||
-.IP "\fB\-l, \-\-length\fP \fIlength\fP" |
||||
-Number of bytes after starting point to discard. Provided value will be |
||||
-aligned to the device sector size. If the specified value extends past |
||||
+KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB and YB. |
||||
+.TP |
||||
+.BR \-o , " \-\-offset \fIoffset" |
||||
+Byte offset into the device from which to start discarding. The provided value |
||||
+will be aligned to the device sector size. The default value is zero. |
||||
+.TP |
||||
+.BR \-l , " \-\-length \fIlength" |
||||
+The number of bytes to discard (counting from the starting point). The provided value |
||||
+will be aligned to the device sector size. If the specified value extends past |
||||
the end of the device, |
||||
.B blkdiscard |
||||
-will stop at the device size boundary. Default value extends to the end |
||||
+will stop at the device size boundary. The default value extends to the end |
||||
of the device. |
||||
-.IP "\fB\-s, \-\-secure\fP" |
||||
-Perform secure discard. Secure discard is the same as regular discard |
||||
-except all copies of the discarded blocks possibly created by garbage |
||||
-collection must also be erased. It has to be supported by the device. |
||||
-.IP "\fB\-v, \-\-verbose\fP" |
||||
-Print aligned |
||||
+.TP |
||||
+.BR \-p , " \-\-step \fIlength" |
||||
+The number of bytes to discard within one iteration. The default is to discard |
||||
+all by one ioctl call. |
||||
+.TP |
||||
+.BR \-s , " \-\-secure" |
||||
+Perform a secure discard. A secure discard is the same as a regular discard |
||||
+except that all copies of the discarded blocks that were possibly created by |
||||
+garbage collection must also be erased. This requires support from the device. |
||||
+.TP |
||||
+.BR \-v , " \-\-verbose" |
||||
+Display the aligned values of |
||||
.I offset |
||||
and |
||||
-.I length |
||||
-arguments. |
||||
+.IR length . |
||||
+If the option \fB\-\-step\fR specified than it prints discard progress every second. |
||||
+.TP |
||||
+.BR \-V , " \-\-version" |
||||
+Display version information and exit. |
||||
+.TP |
||||
+.BR \-h , " \-\-help" |
||||
+Display help text and exit. |
||||
.SH AUTHOR |
||||
.MT lczerner@redhat.com |
||||
Lukas Czerner |
||||
diff -up util-linux-2.23.2/sys-utils/blkdiscard.c.kzak util-linux-2.23.2/sys-utils/blkdiscard.c |
||||
--- util-linux-2.23.2/sys-utils/blkdiscard.c.kzak 2013-07-30 10:39:26.337739534 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/blkdiscard.c 2014-10-27 10:03:20.981088614 +0100 |
||||
@@ -31,9 +31,11 @@ |
||||
#include <fcntl.h> |
||||
#include <limits.h> |
||||
#include <getopt.h> |
||||
+#include <time.h> |
||||
|
||||
#include <sys/ioctl.h> |
||||
#include <sys/stat.h> |
||||
+#include <sys/time.h> |
||||
#include <linux/fs.h> |
||||
|
||||
#include "nls.h" |
||||
@@ -49,6 +51,10 @@ |
||||
#define BLKSECDISCARD _IO(0x12,125) |
||||
#endif |
||||
|
||||
+#define print_stats(path, stats) \ |
||||
+ printf(_("%s: Discarded %" PRIu64 " bytes from the " \ |
||||
+ "offset %" PRIu64"\n"), path, stats[1], stats[0]); |
||||
+ |
||||
static void __attribute__((__noreturn__)) usage(FILE *out) |
||||
{ |
||||
fputs(USAGE_HEADER, out); |
||||
@@ -57,6 +63,7 @@ static void __attribute__((__noreturn__) |
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -o, --offset <num> offset in bytes to discard from\n" |
||||
" -l, --length <num> length of bytes to discard from the offset\n" |
||||
+ " -p, --step <num> size of the discard iterations within the offset\n" |
||||
" -s, --secure perform secure discard\n" |
||||
" -v, --verbose print aligned length and offset\n"), |
||||
out); |
||||
@@ -70,15 +77,17 @@ static void __attribute__((__noreturn__) |
||||
int main(int argc, char **argv) |
||||
{ |
||||
char *path; |
||||
- int c, fd, verbose = 0, secure = 0; |
||||
- uint64_t end, blksize, secsize, range[2]; |
||||
+ int c, fd, verbose = 0, secure = 0, secsize; |
||||
+ uint64_t end, blksize, step, range[2], stats[2]; |
||||
struct stat sb; |
||||
+ struct timespec now, last; |
||||
|
||||
static const struct option longopts[] = { |
||||
{ "help", 0, 0, 'h' }, |
||||
{ "version", 0, 0, 'V' }, |
||||
{ "offset", 1, 0, 'o' }, |
||||
{ "length", 1, 0, 'l' }, |
||||
+ { "step", 1, 0, 'p' }, |
||||
{ "secure", 0, 0, 's' }, |
||||
{ "verbose", 0, 0, 'v' }, |
||||
{ NULL, 0, 0, 0 } |
||||
@@ -91,8 +100,9 @@ int main(int argc, char **argv) |
||||
|
||||
range[0] = 0; |
||||
range[1] = ULLONG_MAX; |
||||
+ step = 0; |
||||
|
||||
- while ((c = getopt_long(argc, argv, "hVsvo:l:", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "hVsvo:l:p:", longopts, NULL)) != -1) { |
||||
switch(c) { |
||||
case 'h': |
||||
usage(stdout); |
||||
@@ -108,6 +118,10 @@ int main(int argc, char **argv) |
||||
range[0] = strtosize_or_err(optarg, |
||||
_("failed to parse offset")); |
||||
break; |
||||
+ case 'p': |
||||
+ step = strtosize_or_err(optarg, |
||||
+ _("failed to parse step")); |
||||
+ break; |
||||
case 's': |
||||
secure = 1; |
||||
break; |
||||
@@ -121,7 +135,7 @@ int main(int argc, char **argv) |
||||
} |
||||
|
||||
if (optind == argc) |
||||
- errx(EXIT_FAILURE, _("no device specified.")); |
||||
+ errx(EXIT_FAILURE, _("no device specified")); |
||||
|
||||
path = argv[optind++]; |
||||
|
||||
@@ -130,43 +144,69 @@ int main(int argc, char **argv) |
||||
usage(stderr); |
||||
} |
||||
|
||||
- if (stat(path, &sb) == -1) |
||||
- err(EXIT_FAILURE, _("stat failed %s"), path); |
||||
- if (!S_ISBLK(sb.st_mode)) |
||||
- errx(EXIT_FAILURE, _("%s: not a block device"), path); |
||||
- |
||||
fd = open(path, O_WRONLY); |
||||
if (fd < 0) |
||||
err(EXIT_FAILURE, _("cannot open %s"), path); |
||||
|
||||
+ if (fstat(fd, &sb) == -1) |
||||
+ err(EXIT_FAILURE, _("stat failed %s"), path); |
||||
+ if (!S_ISBLK(sb.st_mode)) |
||||
+ errx(EXIT_FAILURE, _("%s: not a block device"), path); |
||||
+ |
||||
if (ioctl(fd, BLKGETSIZE64, &blksize)) |
||||
err(EXIT_FAILURE, _("%s: BLKGETSIZE64 ioctl failed"), path); |
||||
- |
||||
if (ioctl(fd, BLKSSZGET, &secsize)) |
||||
err(EXIT_FAILURE, _("%s: BLKSSZGET ioctl failed"), path); |
||||
|
||||
- /* align range to the sector size */ |
||||
- range[0] = (range[0] + secsize - 1) & ~(secsize - 1); |
||||
- range[1] &= ~(secsize - 1); |
||||
+ /* check offset alignment to the sector size */ |
||||
+ if (range[0] % secsize) |
||||
+ errx(EXIT_FAILURE, _("%s: offset %" PRIu64 " is not aligned " |
||||
+ "to sector size %i"), path, range[0], secsize); |
||||
|
||||
/* is the range end behind the end of the device ?*/ |
||||
+ if (range[0] > blksize) |
||||
+ errx(EXIT_FAILURE, _("%s: offset is greater than device size"), path); |
||||
end = range[0] + range[1]; |
||||
if (end < range[0] || end > blksize) |
||||
- range[1] = blksize - range[0]; |
||||
+ end = blksize; |
||||
+ |
||||
+ range[1] = (step > 0) ? step : end - range[0]; |
||||
+ |
||||
+ /* check length alignment to the sector size */ |
||||
+ if (range[1] % secsize) |
||||
+ errx(EXIT_FAILURE, _("%s: length %" PRIu64 " is not aligned " |
||||
+ "to sector size %i"), path, range[1], secsize); |
||||
+ |
||||
+ stats[0] = range[0], stats[1] = 0; |
||||
+ clock_gettime(CLOCK_MONOTONIC, &last); |
||||
+ |
||||
+ for (range[0] = range[0]; range[0] < end; range[0] += range[1]) { |
||||
+ if (range[0] + range[1] > end) |
||||
+ range[1] = end - range[0]; |
||||
+ |
||||
+ if (secure) { |
||||
+ if (ioctl(fd, BLKSECDISCARD, &range)) |
||||
+ err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path); |
||||
+ } else { |
||||
+ if (ioctl(fd, BLKDISCARD, &range)) |
||||
+ err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path); |
||||
+ } |
||||
+ |
||||
+ /* reporting progress */ |
||||
+ if (verbose && step) { |
||||
+ clock_gettime(CLOCK_MONOTONIC, &now); |
||||
+ if (last.tv_sec < now.tv_sec) { |
||||
+ print_stats(path, stats); |
||||
+ stats[0] = range[0], stats[1] = 0; |
||||
+ last = now; |
||||
+ } |
||||
+ } |
||||
|
||||
- if (secure) { |
||||
- if (ioctl(fd, BLKSECDISCARD, &range)) |
||||
- err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path); |
||||
- } else { |
||||
- if (ioctl(fd, BLKDISCARD, &range)) |
||||
- err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path); |
||||
+ stats[1] += range[1]; |
||||
} |
||||
|
||||
if (verbose) |
||||
- /* TRANSLATORS: The standard value here is a very large number. */ |
||||
- printf(_("%s: Discarded %" PRIu64 " bytes from the " |
||||
- "offset %" PRIu64"\n"), path, |
||||
- (uint64_t) range[1], (uint64_t) range[0]); |
||||
+ print_stats(path, stats); |
||||
|
||||
close(fd); |
||||
return EXIT_SUCCESS; |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/dos.c.kzak util-linux-2.23.2/libblkid/src/partitions/dos.c |
||||
--- util-linux-2.23.2/libblkid/src/partitions/dos.c.kzak 2015-08-21 10:16:45.244332027 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/dos.c 2015-08-21 10:22:07.181340367 +0200 |
||||
@@ -151,16 +151,6 @@ static int probe_dos_pt(blkid_probe pr, |
||||
if (memcmp(data, BLKID_AIX_MAGIC_STRING, BLKID_AIX_MAGIC_STRLEN) == 0) |
||||
goto nothing; |
||||
|
||||
- /* |
||||
- * Now that the 55aa signature is present, this is probably |
||||
- * either the boot sector of a FAT filesystem or a DOS-type |
||||
- * partition table. |
||||
- */ |
||||
- if (blkid_probe_is_vfat(pr) == 1) { |
||||
- DBG(LOWPROBE, blkid_debug("probably FAT -- ignore")); |
||||
- goto nothing; |
||||
- } |
||||
- |
||||
p0 = (struct dos_partition *) (data + BLKID_MSDOS_PT_OFFSET); |
||||
|
||||
/* |
||||
@@ -182,6 +172,16 @@ static int probe_dos_pt(blkid_probe pr, |
||||
} |
||||
} |
||||
|
||||
+ /* |
||||
+ * Now that the 55aa signature is present, this is probably |
||||
+ * either the boot sector of a FAT filesystem or a DOS-type |
||||
+ * partition table. |
||||
+ */ |
||||
+ if (blkid_probe_is_vfat(pr) == 1) { |
||||
+ DBG(LOWPROBE, blkid_debug("probably FAT -- ignore")); |
||||
+ goto nothing; |
||||
+ } |
||||
+ |
||||
blkid_probe_use_wiper(pr, BLKID_MSDOS_PT_OFFSET, |
||||
512 - BLKID_MSDOS_PT_OFFSET); |
||||
|
||||
diff -up util-linux-2.23.2/libblkid/src/partitions/dos.h.kzak util-linux-2.23.2/libblkid/src/partitions/dos.h |
||||
--- util-linux-2.23.2/libblkid/src/partitions/dos.h.kzak 2015-08-21 10:34:14.919380422 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/partitions/dos.h 2015-08-21 10:35:45.221807669 +0200 |
||||
@@ -12,6 +12,12 @@ struct dos_partition { |
||||
|
||||
#define BLKID_MSDOS_PT_OFFSET 0x1be |
||||
|
||||
+static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i) |
||||
+{ |
||||
+ return (struct dos_partition *) |
||||
+ (mbr + BLKID_MSDOS_PT_OFFSET + (i * sizeof(struct dos_partition))); |
||||
+} |
||||
+ |
||||
/* assemble badly aligned little endian integer */ |
||||
static inline unsigned int assemble4le(const unsigned char *p) |
||||
{ |
||||
diff -up util-linux-2.23.2/libblkid/src/superblocks/vfat.c.kzak util-linux-2.23.2/libblkid/src/superblocks/vfat.c |
||||
--- util-linux-2.23.2/libblkid/src/superblocks/vfat.c.kzak 2015-08-21 10:10:12.111906711 +0200 |
||||
+++ util-linux-2.23.2/libblkid/src/superblocks/vfat.c 2015-08-21 10:35:07.733045452 +0200 |
||||
@@ -16,6 +16,7 @@ |
||||
#include <ctype.h> |
||||
#include <stdint.h> |
||||
|
||||
+#include "partitions/dos.h" |
||||
#include "superblocks.h" |
||||
|
||||
/* Yucky misaligned values */ |
||||
@@ -169,7 +170,8 @@ static unsigned char *search_fat_label(b |
||||
return NULL; |
||||
} |
||||
|
||||
-static int fat_valid_superblock(const struct blkid_idmag *mag, |
||||
+static int fat_valid_superblock(blkid_probe pr, |
||||
+ const struct blkid_idmag *mag, |
||||
struct msdos_super_block *ms, |
||||
struct vfat_super_block *vs, |
||||
uint32_t *cluster_count, uint32_t *fat_size) |
||||
@@ -243,6 +245,20 @@ static int fat_valid_superblock(const st |
||||
if (cluster_count) |
||||
*cluster_count = __cluster_count; |
||||
|
||||
+ if (blkid_probe_is_wholedisk(pr)) { |
||||
+ /* OK, seems like FAT, but it's possible that we found boot |
||||
+ * sector with crazy FAT-like stuff (magic strings, media, |
||||
+ * etc..) before MBR. Let's make sure that there is no MBR with |
||||
+ * usable partition. */ |
||||
+ unsigned char *buf = (unsigned char *) ms; |
||||
+ if (is_valid_mbr_signature(buf)) { |
||||
+ struct dos_partition *p0 = mbr_get_partition(buf, 0); |
||||
+ if (dos_partition_size(p0) != 0 && |
||||
+ (p0->boot_ind == 0 || p0->boot_ind == 0x80)) |
||||
+ return 0; |
||||
+ } |
||||
+ } |
||||
+ |
||||
return 1; /* valid */ |
||||
} |
||||
|
||||
@@ -270,7 +286,7 @@ int blkid_probe_is_vfat(blkid_probe pr) |
||||
if (!vs) |
||||
return errno ? -errno : 0; |
||||
|
||||
- return fat_valid_superblock(mag, ms, vs, NULL, NULL); |
||||
+ return fat_valid_superblock(pr, mag, ms, vs, NULL, NULL); |
||||
} |
||||
|
||||
/* FAT label extraction from the root directory taken from Kay |
||||
@@ -293,7 +309,7 @@ static int probe_vfat(blkid_probe pr, co |
||||
if (!vs) |
||||
return errno ? -errno : 1; |
||||
|
||||
- if (!fat_valid_superblock(mag, ms, vs, &cluster_count, &fat_size)) |
||||
+ if (!fat_valid_superblock(pr, mag, ms, vs, &cluster_count, &fat_size)) |
||||
return 1; |
||||
|
||||
sector_size = unaligned_le16(&ms->ms_sector_size); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/logger.1.kzak util-linux-2.23.2/misc-utils/logger.1 |
||||
--- util-linux-2.23.2/misc-utils/logger.1.kzak 2015-06-24 12:18:23.938735038 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/logger.1 2015-06-24 12:18:33.154667053 +0200 |
||||
@@ -125,28 +125,49 @@ flag is not provided, standard input is |
||||
The |
||||
.B logger |
||||
utility exits 0 on success, and >0 if an error occurs. |
||||
-.PP |
||||
+.SH FACILITIES AND LEVELS |
||||
Valid facility names are: |
||||
-.IR auth , \ authpriv |
||||
-(for security information of a sensitive nature), |
||||
-.IR cron , \ daemon , \ ftp , \ kern |
||||
-(can't be generated from user process), |
||||
-.IR lpr , \ mail , \ news , \ security |
||||
-(deprecated synonym for |
||||
-.IR auth ), \ syslog , \ user , \ uucp , |
||||
-and |
||||
-.IR local0 \ to \ local7 , |
||||
-inclusive. |
||||
+.IP |
||||
+.TS |
||||
+tab(:); |
||||
+left l l. |
||||
+\fBauth |
||||
+\fBauthpriv\fR:for security information of a sensitive nature |
||||
+\fBcron |
||||
+\fBdaemon |
||||
+\fBftp |
||||
+\fBkern\fR:cannot be generated from userspace process, automatically converted to \fBuser |
||||
+\fBlpr |
||||
+\fBmail |
||||
+\fBnews |
||||
+\fBsyslog |
||||
+\fBuser |
||||
+\fBuucp |
||||
+\fBlocal0 |
||||
+ to: |
||||
+\fBlocal7 |
||||
+\fBsecurity\fR:deprecated synonym for \fBauth |
||||
+.TE |
||||
.PP |
||||
Valid level names are: |
||||
-.IR alert , \ crit , \ debug , \ emerg , \ err , \ error |
||||
-(deprecated synonym for |
||||
-.IR err ), \ info , \ notice , \ panic |
||||
-(deprecated synonym for |
||||
-.IR emerg ), \ warning , \ warn |
||||
-(deprecated synonym for |
||||
-.IR warning ). |
||||
-For the priority order and intended purposes of these levels, see |
||||
+.IP |
||||
+.TS |
||||
+tab(:); |
||||
+left l l. |
||||
+\fBemerg |
||||
+\fBalert |
||||
+\fBcrit |
||||
+\fBerr |
||||
+\fBwarning |
||||
+\fBnotice |
||||
+\fBinfo |
||||
+\fBdebug |
||||
+\fBpanic\fR:deprecated synonym for \fBemerg |
||||
+\fBerror\fR:deprecated synonym for \fBerr |
||||
+\fBwarn\fR:deprecated synonym for \fBwarning |
||||
+.TE |
||||
+.PP |
||||
+For the priority order and intended purposes of these facilities and levels, see |
||||
.BR syslog (3). |
||||
.SH EXAMPLES |
||||
logger System rebooted |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
diff -up util-linux-2.23.2/login-utils/login.c.kzak util-linux-2.23.2/login-utils/login.c |
||||
--- util-linux-2.23.2/login-utils/login.c.kzak 2015-06-24 11:03:45.123285155 +0200 |
||||
+++ util-linux-2.23.2/login-utils/login.c 2015-06-24 11:46:19.168114438 +0200 |
||||
@@ -495,6 +495,7 @@ static void log_audit(struct login_conte |
||||
|
||||
static void log_lastlog(struct login_context *cxt) |
||||
{ |
||||
+ struct sigaction sa, oldsa_xfsz; |
||||
struct lastlog ll; |
||||
time_t t; |
||||
int fd; |
||||
@@ -502,9 +503,14 @@ static void log_lastlog(struct login_con |
||||
if (!cxt->pwd) |
||||
return; |
||||
|
||||
+ /* lastlog is huge on systems with large UIDs, ignore SIGXFSZ */ |
||||
+ memset(&sa, 0, sizeof(sa)); |
||||
+ sa.sa_handler = SIG_IGN; |
||||
+ sigaction(SIGXFSZ, &sa, &oldsa_xfsz); |
||||
+ |
||||
fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0); |
||||
if (fd < 0) |
||||
- return; |
||||
+ goto done; |
||||
|
||||
if (lseek(fd, (off_t) cxt->pwd->pw_uid * sizeof(ll), SEEK_SET) == -1) |
||||
goto done; |
||||
@@ -542,7 +548,10 @@ static void log_lastlog(struct login_con |
||||
if (write_all(fd, (char *)&ll, sizeof(ll))) |
||||
warn(_("write lastlog failed")); |
||||
done: |
||||
- close(fd); |
||||
+ if (fd >= 0) |
||||
+ close(fd); |
||||
+ |
||||
+ sigaction(SIGXFSZ, &oldsa_xfsz, NULL); /* restore original setting */ |
||||
} |
||||
|
||||
/* |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
diff -up util-linux-2.23.2/misc-utils/lsblk.c.kzak util-linux-2.23.2/misc-utils/lsblk.c |
||||
--- util-linux-2.23.2/misc-utils/lsblk.c.kzak 2015-06-25 11:01:10.543344225 +0200 |
||||
+++ util-linux-2.23.2/misc-utils/lsblk.c 2015-06-25 11:14:17.085404974 +0200 |
||||
@@ -953,11 +953,13 @@ static void set_tt_data(struct blkdev_cx |
||||
}; |
||||
} |
||||
|
||||
-static void print_device(struct blkdev_cxt *cxt, struct tt_line *tt_parent) |
||||
+static void fill_table_line(struct blkdev_cxt *cxt, struct tt_line *tt_parent) |
||||
{ |
||||
int i; |
||||
|
||||
cxt->tt_line = tt_add_line(lsblk->tt, tt_parent); |
||||
+ if (!cxt->tt_line) |
||||
+ return; |
||||
|
||||
for (i = 0; i < ncolumns; i++) |
||||
set_tt_data(cxt, i, get_column_id(i), cxt->tt_line); |
||||
@@ -1084,7 +1086,7 @@ static int list_partitions(struct blkdev |
||||
goto next; |
||||
|
||||
wholedisk_cxt->parent = &part_cxt; |
||||
- print_device(&part_cxt, parent_cxt ? parent_cxt->tt_line : NULL); |
||||
+ fill_table_line(&part_cxt, parent_cxt ? parent_cxt->tt_line : NULL); |
||||
if (!lsblk->nodeps) |
||||
process_blkdev(wholedisk_cxt, &part_cxt, 0, NULL); |
||||
} else { |
||||
@@ -1098,7 +1100,7 @@ static int list_partitions(struct blkdev |
||||
|
||||
/* Print whole disk only once */ |
||||
if (r) |
||||
- print_device(wholedisk_cxt, parent_cxt ? parent_cxt->tt_line : NULL); |
||||
+ fill_table_line(wholedisk_cxt, parent_cxt ? parent_cxt->tt_line : NULL); |
||||
if (ps == 0 && !lsblk->nodeps) |
||||
process_blkdev(&part_cxt, wholedisk_cxt, 0, NULL); |
||||
} |
||||
@@ -1171,9 +1173,11 @@ static int list_deps(struct blkdev_cxt * |
||||
process_blkdev(&dep, cxt, 1, d->d_name); |
||||
} |
||||
/* The dependency is a whole device. */ |
||||
- else if (!set_cxt(&dep, cxt, NULL, d->d_name)) |
||||
- process_blkdev(&dep, cxt, 1, NULL); |
||||
- |
||||
+ else if (!set_cxt(&dep, cxt, NULL, d->d_name)) { |
||||
+ /* For inverse tree we don't want to show partitions |
||||
+ * if the dependence is pn whle-disk */ |
||||
+ process_blkdev(&dep, cxt, lsblk->inverse ? 0 : 1, NULL); |
||||
+ } |
||||
reset_blkdev_cxt(&dep); |
||||
} |
||||
closedir(dir); |
||||
@@ -1185,9 +1189,10 @@ static int process_blkdev(struct blkdev_ |
||||
int do_partitions, const char *part_name) |
||||
{ |
||||
if (do_partitions && cxt->npartitions) |
||||
- return list_partitions(cxt, parent, part_name); |
||||
+ list_partitions(cxt, parent, part_name); /* partitoins + whole-disk */ |
||||
+ else |
||||
+ fill_table_line(cxt, parent ? parent->tt_line : NULL); /* whole-disk only */ |
||||
|
||||
- print_device(cxt, parent ? parent->tt_line : NULL); |
||||
return list_deps(cxt); |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/mount.8.kzak util-linux-2.23.2/sys-utils/mount.8 |
||||
--- util-linux-2.23.2/sys-utils/mount.8.kzak 2014-09-25 11:03:25.492822164 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/mount.8 2014-09-25 11:04:00.102152375 +0200 |
||||
@@ -451,7 +451,7 @@ has to be a mountpoint. |
||||
|
||||
Note that moving a mount residing under a shared mount is invalid and |
||||
unsupported. Use |
||||
-.B findmnt -o TARGET,PROPAGATION /dir |
||||
+.B findmnt -o TARGET,PROPAGATION |
||||
to see the current propagation flags. |
||||
.RE |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff -up util-linux-2.23.2/disk-utils/raw.c.kzak util-linux-2.23.2/disk-utils/raw.c |
||||
--- util-linux-2.23.2/disk-utils/raw.c.kzak 2013-06-13 09:46:10.382650297 +0200 |
||||
+++ util-linux-2.23.2/disk-utils/raw.c 2015-01-13 14:51:24.877755962 +0100 |
||||
@@ -220,7 +220,7 @@ static int query(int minor_raw, const ch |
||||
if (raw_name) { |
||||
struct stat statbuf; |
||||
|
||||
- if (!stat(raw_name, &statbuf)) |
||||
+ if (stat(raw_name, &statbuf) != 0) |
||||
err(EXIT_RAW_ACCESS, |
||||
_("Cannot locate raw device '%s'"), raw_name); |
||||
if (!S_ISCHR(statbuf.st_mode)) |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
diff -up util-linux-2.23.2/login-utils/su-common.c.kzak util-linux-2.23.2/login-utils/su-common.c |
||||
--- util-linux-2.23.2/login-utils/su-common.c.kzak 2015-06-24 11:14:25.102395082 +0200 |
||||
+++ util-linux-2.23.2/login-utils/su-common.c 2015-06-24 11:22:20.472859684 +0200 |
||||
@@ -359,10 +359,9 @@ create_watching_parent (void) |
||||
if (pid != (pid_t)-1) |
||||
if (WIFSIGNALED (status)) |
||||
{ |
||||
- status = WTERMSIG (status) + 128; |
||||
- if (WCOREDUMP (status)) |
||||
- fprintf (stderr, _("%s (core dumped)\n"), |
||||
- strsignal (WTERMSIG (status))); |
||||
+ fprintf (stderr, "%s%s\n", strsignal (WTERMSIG (status)), |
||||
+ WCOREDUMP (status) ? _(" (core dumped)") : ""); |
||||
+ status = WTERMSIG (status) + 128; |
||||
} |
||||
else |
||||
status = WEXITSTATUS (status); |
@ -0,0 +1,757 @@
@@ -0,0 +1,757 @@
|
||||
diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h |
||||
--- util-linux-2.23.2/include/pathnames.h.kzak 2015-06-26 10:00:19.111877564 +0200 |
||||
+++ util-linux-2.23.2/include/pathnames.h 2015-06-26 10:00:51.623630869 +0200 |
||||
@@ -85,6 +85,10 @@ |
||||
#define _PATH_PROC_LOCKS "/proc/locks" |
||||
#define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info" |
||||
|
||||
+#define _PATH_PROC_UIDMAP "/proc/self/uid_map" |
||||
+#define _PATH_PROC_GIDMAP "/proc/self/gid_map" |
||||
+#define _PATH_PROC_SETGROUPS "/proc/self/setgroups" |
||||
+ |
||||
#define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current" |
||||
#define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec" |
||||
#define _PATH_PROC_CAPLASTCAP "/proc/sys/kernel/cap_last_cap" |
||||
diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am |
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.1.kzak util-linux-2.23.2/sys-utils/nsenter.1 |
||||
--- util-linux-2.23.2/sys-utils/nsenter.1.kzak 2015-06-26 09:58:39.468633643 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.1 2015-06-26 09:58:51.672541041 +0200 |
||||
@@ -1,44 +1,45 @@ |
||||
-.TH NSENTER 1 "January 2013" "util-linux" "User Commands" |
||||
+.TH NSENTER 1 "June 2013" "util-linux" "User Commands" |
||||
.SH NAME |
||||
nsenter \- run program with namespaces of other processes |
||||
.SH SYNOPSIS |
||||
.B nsenter |
||||
-.RI [ options ] |
||||
-.RI [ program ] |
||||
-.RI [ arguments ] |
||||
+[options] |
||||
+.RI [ program |
||||
+.RI [ arguments ]] |
||||
.SH DESCRIPTION |
||||
Enters the namespaces of one or more other processes and then executes the specified |
||||
program. Enterable namespaces are: |
||||
.TP |
||||
.B mount namespace |
||||
-mounting and unmounting filesystems will not affect rest of the system |
||||
+Mounting and unmounting filesystems will not affect the rest of the system |
||||
.RB ( CLONE_\:NEWNS |
||||
-flag), except for filesystems which are explicitly marked as shared (by mount |
||||
---make-\:shared). See /proc\:/self\:/mountinfo for the shared flag. |
||||
+flag), except for filesystems which are explicitly marked as shared (with |
||||
+\fBmount --make-\:shared\fP; see \fI/proc\:/self\:/mountinfo\fP for the |
||||
+\fBshared\fP flag). |
||||
.TP |
||||
.B UTS namespace |
||||
-setting hostname, domainname will not affect rest of the system |
||||
+Setting hostname or domainname will not affect the rest of the system. |
||||
.RB ( CLONE_\:NEWUTS |
||||
-flag). |
||||
+flag) |
||||
.TP |
||||
.B IPC namespace |
||||
-process will have independent namespace for System V message queues, semaphore |
||||
-sets and shared memory segments |
||||
+The process will have an independent namespace for System V message queues, |
||||
+semaphore sets and shared memory segments. |
||||
.RB ( CLONE_\:NEWIPC |
||||
-flag). |
||||
+flag) |
||||
.TP |
||||
.B network namespace |
||||
-process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall |
||||
-rules, the |
||||
+The process will have independent IPv4 and IPv6 stacks, IP routing tables, |
||||
+firewall rules, the |
||||
.I /proc\:/net |
||||
and |
||||
.I /sys\:/class\:/net |
||||
-directory trees, sockets etc. |
||||
+directory trees, sockets, etc. |
||||
.RB ( CLONE_\:NEWNET |
||||
-flag). |
||||
+flag) |
||||
.TP |
||||
.B PID namespace |
||||
-children will have a set of PID to process mappings separate from the |
||||
+Children will have a set of PID to process mappings separate from the |
||||
.B nsenter |
||||
process |
||||
.RB ( CLONE_\:NEWPID |
||||
@@ -46,18 +47,18 @@ flag). |
||||
.B nsenter |
||||
will fork by default if changing the PID namespace, so that the new program |
||||
and its children share the same PID namespace and are visible to each other. |
||||
-If \-\-no\-fork is used, the new program will be exec'ed without forking. |
||||
-.PP |
||||
-See the |
||||
-.BR clone (2) |
||||
-for exact semantics of the flags. |
||||
+If \fB\-\-no\-fork\fP is used, the new program will be exec'ed without forking. |
||||
.TP |
||||
-If program is not given, run ``${SHELL}'' (default: /bin\:/sh). |
||||
+.B user namespace |
||||
+The process will have a distinct set of UIDs, GIDs and capabilities. |
||||
+.RB ( CLONE_\:NEWUSER |
||||
+flag) |
||||
+.TP |
||||
+See \fBclone\fP(2) for the exact semantics of the flags. |
||||
+.TP |
||||
+If \fIprogram\fP is not given, then ``${SHELL}'' is run (default: /bin\:/sh). |
||||
|
||||
.SH OPTIONS |
||||
-Argument with square brakets, such as [\fIfile\fR], means optional argument. |
||||
-Command line syntax to specify optional argument \-\-mount=/path\:/to\:/file. |
||||
-Please notice the equals sign. |
||||
.TP |
||||
\fB\-t\fR, \fB\-\-target\fR \fIpid\fP |
||||
Specify a target process to get contexts from. The paths to the contexts |
||||
@@ -83,6 +84,9 @@ the network namespace |
||||
/proc/\fIpid\fR/ns/pid |
||||
the PID namespace |
||||
.TP |
||||
+/proc/\fIpid\fR/ns/user |
||||
+the user namespace |
||||
+.TP |
||||
/proc/\fIpid\fR/root |
||||
the root directory |
||||
.TP |
||||
@@ -91,51 +95,71 @@ the working directory respectively |
||||
.PD |
||||
.RE |
||||
.TP |
||||
-\fB\-m\fR, \fB\-\-mount\fR [\fIfile\fR] |
||||
-Enter the mount namespace. If no file is specified enter the mount namespace |
||||
-of the target process. If file is specified enter the mount namespace |
||||
+\fB\-m\fR, \fB\-\-mount\fR[=\fIfile\fR] |
||||
+Enter the mount namespace. If no file is specified, enter the mount namespace |
||||
+of the target process. If file is specified, enter the mount namespace |
||||
specified by file. |
||||
.TP |
||||
-\fB\-u\fR, \fB\-\-uts\fR [\fIfile\fR] |
||||
-Enter the UTS namespace. If no file is specified enter the UTS namespace of |
||||
-the target process. If file is specified enter the UTS namespace specified by |
||||
+\fB\-u\fR, \fB\-\-uts\fR[=\fIfile\fR] |
||||
+Enter the UTS namespace. If no file is specified, enter the UTS namespace of |
||||
+the target process. If file is specified, enter the UTS namespace specified by |
||||
file. |
||||
.TP |
||||
-\fB\-i\fR, \fB\-\-ipc\fR [\fIfile\fR] |
||||
-Enter the IPC namespace. If no file is specified enter the IPC namespace of |
||||
-the target process. If file is specified enter the IPC namespace specified by |
||||
+\fB\-i\fR, \fB\-\-ipc\fR[=\fIfile\fR] |
||||
+Enter the IPC namespace. If no file is specified, enter the IPC namespace of |
||||
+the target process. If file is specified, enter the IPC namespace specified by |
||||
file. |
||||
.TP |
||||
-\fB\-n\fR, \fB\-\-net\fR [\fIfile\fR] |
||||
-Enter the network namespace. If no file is specified enter the network |
||||
-namespace of the target process. If file is specified enter the network |
||||
+\fB\-n\fR, \fB\-\-net\fR[=\fIfile\fR] |
||||
+Enter the network namespace. If no file is specified, enter the network |
||||
+namespace of the target process. If file is specified, enter the network |
||||
namespace specified by file. |
||||
.TP |
||||
-\fB\-p\fR, \fB\-\-pid\fR [\fIfile\fR] |
||||
-Enter the PID namespace. If no file is specified enter the PID namespace of |
||||
-the target process. If file is specified enter the PID namespace specified by |
||||
+\fB\-p\fR, \fB\-\-pid\fR[=\fIfile\fR] |
||||
+Enter the PID namespace. If no file is specified, enter the PID namespace of |
||||
+the target process. If file is specified, enter the PID namespace specified by |
||||
file. |
||||
.TP |
||||
-\fB\-r\fR, \fB\-\-root\fR [\fIdirectory\fR] |
||||
-Set the root directory. If no directory is specified set the root directory to |
||||
-the root directory of the target process. If directory is specified set the |
||||
+\fB\-U\fR, \fB\-\-user\fR[=\fIfile\fR] |
||||
+Enter the user namespace. If no file is specified, enter the user namespace of |
||||
+the target process. If file is specified, enter the user namespace specified by |
||||
+file. See also the \fB\-\-setuid\fR and \fB\-\-setgid\fR options. |
||||
+.TP |
||||
+\fB\-G\fR, \fB\-\-setgid\fR \fIgid\fR |
||||
+Set the group ID which will be used in the entered namespace and drop |
||||
+supplementary groups. |
||||
+.BR nsenter (1) |
||||
+always sets GID for user namespaces, the default is 0. |
||||
+.TP |
||||
+\fB\-S\fR, \fB\-\-setuid\fR \fIuid\fR |
||||
+Set the user ID which will be used in the entered namespace. |
||||
+.BR nsenter (1) |
||||
+always sets UID for user namespaces, the default is 0. |
||||
+.TP |
||||
+\fB\-\-preserve\-credentials\fR |
||||
+Don't modify UID and GID when enter user namespace. The default is to |
||||
+drops supplementary groups and sets GID and UID to 0. |
||||
+.TP |
||||
+\fB\-r\fR, \fB\-\-root\fR[=\fIdirectory\fR] |
||||
+Set the root directory. If no directory is specified, set the root directory to |
||||
+the root directory of the target process. If directory is specified, set the |
||||
root directory to the specified directory. |
||||
.TP |
||||
-\fB\-w\fR, \fB\-\-wd\fR [\fIdirectory\fR] |
||||
-Set the working directory. If no directory is specified set the working |
||||
+\fB\-w\fR, \fB\-\-wd\fR[=\fIdirectory\fR] |
||||
+Set the working directory. If no directory is specified, set the working |
||||
directory to the working directory of the target process. If directory is |
||||
-specified set the working directory to the specified directory. |
||||
+specified, set the working directory to the specified directory. |
||||
.TP |
||||
-\fB\-F\fR, \fB\-\-no-fork\fR |
||||
-Do not fork before exec'ing the specified program. By default when entering a |
||||
-pid namespace enter calls fork before calling exec so that the children will be |
||||
-in the newly entered pid namespace. |
||||
+\fB\-F\fR, \fB\-\-no\-fork\fR |
||||
+Do not fork before exec'ing the specified program. By default, when entering a |
||||
+PID namespace, \fBnsenter\fP calls \fBfork\fP before calling \fBexec\fP so that |
||||
+any children will also be in the newly entered PID namespace. |
||||
.TP |
||||
\fB\-V\fR, \fB\-\-version\fR |
||||
Display version information and exit. |
||||
.TP |
||||
\fB\-h\fR, \fB\-\-help\fR |
||||
-Print a help message. |
||||
+Display help text and exit. |
||||
.SH SEE ALSO |
||||
.BR setns (2), |
||||
.BR clone (2) |
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.c.kzak util-linux-2.23.2/sys-utils/nsenter.c |
||||
--- util-linux-2.23.2/sys-utils/nsenter.c.kzak 2015-06-26 09:58:39.468633643 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.c 2015-06-26 09:58:51.673541033 +0200 |
||||
@@ -28,6 +28,7 @@ |
||||
#include <assert.h> |
||||
#include <sys/types.h> |
||||
#include <sys/wait.h> |
||||
+#include <grp.h> |
||||
|
||||
#include "strutils.h" |
||||
#include "nls.h" |
||||
@@ -42,7 +43,12 @@ static struct namespace_file { |
||||
int fd; |
||||
} namespace_files[] = { |
||||
/* Careful the order is significant in this array. |
||||
+ * |
||||
+ * The user namespace comes first, so that it is entered |
||||
+ * first. This gives an unprivileged user the potential to |
||||
+ * enter the other namespaces. |
||||
*/ |
||||
+ { .nstype = CLONE_NEWUSER, .name = "ns/user", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWIPC, .name = "ns/ipc", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWUTS, .name = "ns/uts", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWNET, .name = "ns/net", .fd = -1 }, |
||||
@@ -56,18 +62,25 @@ static void usage(int status) |
||||
FILE *out = status == EXIT_SUCCESS ? stdout : stderr; |
||||
|
||||
fputs(USAGE_HEADER, out); |
||||
- fprintf(out, _(" %s [options] <program> [args...]\n"), |
||||
+ fprintf(out, _(" %s [options] <program> [<argument>...]\n"), |
||||
program_invocation_short_name); |
||||
|
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Run a program with namespaces of other processes.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -t, --target <pid> target process to get namespaces from\n"), out); |
||||
- fputs(_(" -m, --mount [=<file>] enter mount namespace\n"), out); |
||||
- fputs(_(" -u, --uts [=<file>] enter UTS namespace (hostname etc)\n"), out); |
||||
- fputs(_(" -i, --ipc [=<file>] enter System V IPC namespace\n"), out); |
||||
- fputs(_(" -n, --net [=<file>] enter network namespace\n"), out); |
||||
- fputs(_(" -p, --pid [=<file>] enter pid namespace\n"), out); |
||||
- fputs(_(" -r, --root [=<dir>] set the root directory\n"), out); |
||||
- fputs(_(" -w, --wd [=<dir>] set the working directory\n"), out); |
||||
+ fputs(_(" -m, --mount[=<file>] enter mount namespace\n"), out); |
||||
+ fputs(_(" -u, --uts[=<file>] enter UTS namespace (hostname etc)\n"), out); |
||||
+ fputs(_(" -i, --ipc[=<file>] enter System V IPC namespace\n"), out); |
||||
+ fputs(_(" -n, --net[=<file>] enter network namespace\n"), out); |
||||
+ fputs(_(" -p, --pid[=<file>] enter pid namespace\n"), out); |
||||
+ fputs(_(" -U, --user[=<file>] enter user namespace\n"), out); |
||||
+ fputs(_(" -S, --setuid <uid> set uid in entered namespace\n"), out); |
||||
+ fputs(_(" -G, --setgid <gid> set gid in entered namespace\n"), out); |
||||
+ fputs(_(" --preserve-credentials do not touch uids or gids\n"), out); |
||||
+ fputs(_(" -r, --root[=<dir>] set the root directory\n"), out); |
||||
+ fputs(_(" -w, --wd[=<dir>] set the working directory\n"), out); |
||||
fputs(_(" -F, --no-fork do not fork before exec'ing <program>\n"), out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
@@ -153,6 +166,9 @@ static void continue_as_child(void) |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
+ enum { |
||||
+ OPT_PRESERVE_CRED = CHAR_MAX + 1 |
||||
+ }; |
||||
static const struct option longopts[] = { |
||||
{ "help", no_argument, NULL, 'h' }, |
||||
{ "version", no_argument, NULL, 'V'}, |
||||
@@ -162,24 +178,30 @@ int main(int argc, char *argv[]) |
||||
{ "ipc", optional_argument, NULL, 'i' }, |
||||
{ "net", optional_argument, NULL, 'n' }, |
||||
{ "pid", optional_argument, NULL, 'p' }, |
||||
+ { "user", optional_argument, NULL, 'U' }, |
||||
+ { "setuid", required_argument, NULL, 'S' }, |
||||
+ { "setgid", required_argument, NULL, 'G' }, |
||||
{ "root", optional_argument, NULL, 'r' }, |
||||
{ "wd", optional_argument, NULL, 'w' }, |
||||
{ "no-fork", no_argument, NULL, 'F' }, |
||||
+ { "preserve-credentials", no_argument, NULL, OPT_PRESERVE_CRED }, |
||||
{ NULL, 0, NULL, 0 } |
||||
}; |
||||
|
||||
struct namespace_file *nsfile; |
||||
- int c, namespaces = 0; |
||||
- bool do_rd = false, do_wd = false; |
||||
+ int c, namespaces = 0, setgroups_nerrs = 0, preserve_cred = 0; |
||||
+ bool do_rd = false, do_wd = false, force_uid = false, force_gid = false; |
||||
int do_fork = -1; /* unknown yet */ |
||||
+ uid_t uid = 0; |
||||
+ gid_t gid = 0; |
||||
|
||||
- setlocale(LC_MESSAGES, ""); |
||||
+ setlocale(LC_ALL, ""); |
||||
bindtextdomain(PACKAGE, LOCALEDIR); |
||||
textdomain(PACKAGE); |
||||
atexit(close_stdout); |
||||
|
||||
while ((c = |
||||
- getopt_long(argc, argv, "hVt:m::u::i::n::p::r::w::F", |
||||
+ getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::F", |
||||
longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'h': |
||||
@@ -221,6 +243,20 @@ int main(int argc, char *argv[]) |
||||
else |
||||
namespaces |= CLONE_NEWPID; |
||||
break; |
||||
+ case 'U': |
||||
+ if (optarg) |
||||
+ open_namespace_fd(CLONE_NEWUSER, optarg); |
||||
+ else |
||||
+ namespaces |= CLONE_NEWUSER; |
||||
+ break; |
||||
+ case 'S': |
||||
+ uid = strtoul_or_err(optarg, _("failed to parse uid")); |
||||
+ force_uid = true; |
||||
+ break; |
||||
+ case 'G': |
||||
+ gid = strtoul_or_err(optarg, _("failed to parse gid")); |
||||
+ force_gid = true; |
||||
+ break; |
||||
case 'F': |
||||
do_fork = 0; |
||||
break; |
||||
@@ -236,6 +272,9 @@ int main(int argc, char *argv[]) |
||||
else |
||||
do_wd = true; |
||||
break; |
||||
+ case OPT_PRESERVE_CRED: |
||||
+ preserve_cred = 1; |
||||
+ break; |
||||
default: |
||||
usage(EXIT_FAILURE); |
||||
} |
||||
@@ -253,6 +292,26 @@ int main(int argc, char *argv[]) |
||||
open_target_fd(&wd_fd, "cwd", NULL); |
||||
|
||||
/* |
||||
+ * Update namespaces variable to contain all requested namespaces |
||||
+ */ |
||||
+ for (nsfile = namespace_files; nsfile->nstype; nsfile++) { |
||||
+ if (nsfile->fd < 0) |
||||
+ continue; |
||||
+ namespaces |= nsfile->nstype; |
||||
+ } |
||||
+ |
||||
+ /* for user namespaces we always set UID and GID (default is 0) |
||||
+ * and clear root's groups if --preserve-credentials is no specified */ |
||||
+ if ((namespaces & CLONE_NEWUSER) && !preserve_cred) { |
||||
+ force_uid = true, force_gid = true; |
||||
+ |
||||
+ /* We call setgroups() before and after we enter user namespace, |
||||
+ * let's complain only if both fail */ |
||||
+ if (setgroups(0, NULL) != 0) |
||||
+ setgroups_nerrs++; |
||||
+ } |
||||
+ |
||||
+ /* |
||||
* Now that we know which namespaces we want to enter, enter them. |
||||
*/ |
||||
for (nsfile = namespace_files; nsfile->nstype; nsfile++) { |
||||
@@ -302,6 +361,15 @@ int main(int argc, char *argv[]) |
||||
if (do_fork == 1) |
||||
continue_as_child(); |
||||
|
||||
+ if (force_uid || force_gid) { |
||||
+ if (force_gid && setgroups(0, NULL) != 0 && setgroups_nerrs) /* drop supplementary groups */ |
||||
+ err(EXIT_FAILURE, _("setgroups failed")); |
||||
+ if (force_gid && setgid(gid) < 0) /* change GID */ |
||||
+ err(EXIT_FAILURE, _("setgid failed")); |
||||
+ if (force_uid && setuid(uid) < 0) /* change UID */ |
||||
+ err(EXIT_FAILURE, _("setuid failed")); |
||||
+ } |
||||
+ |
||||
if (optind < argc) { |
||||
execvp(argv[optind], argv + optind); |
||||
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]); |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.1.kzak util-linux-2.23.2/sys-utils/unshare.1 |
||||
--- util-linux-2.23.2/sys-utils/unshare.1.kzak 2015-06-26 09:58:39.484633521 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.1 2015-06-26 09:58:51.673541033 +0200 |
||||
@@ -1,28 +1,27 @@ |
||||
-.\" Process this file with |
||||
-.\" groff -man -Tascii lscpu.1 |
||||
-.\" |
||||
-.TH UNSHARE 1 "July 2013" "util-linux" "User Commands" |
||||
+.TH UNSHARE 1 "July 2014" "util-linux" "User Commands" |
||||
.SH NAME |
||||
unshare \- run program with some namespaces unshared from parent |
||||
.SH SYNOPSIS |
||||
.B unshare |
||||
-.RI [ options ] |
||||
+[options] |
||||
.I program |
||||
.RI [ arguments ] |
||||
.SH DESCRIPTION |
||||
Unshares the indicated namespaces from the parent process and then executes |
||||
-the specified program. The namespaces to be unshared are indicated via |
||||
+the specified \fIprogram\fR. The namespaces to be unshared are indicated via |
||||
options. Unshareable namespaces are: |
||||
.TP |
||||
.BR "mount namespace" |
||||
Mounting and unmounting filesystems will not affect the rest of the system |
||||
(\fBCLONE_NEWNS\fP flag), except for filesystems which are explicitly marked as |
||||
-shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP for the |
||||
-\fBshared\fP flags). |
||||
- |
||||
-It's recommended to use \fBmount --make-rprivate\fP or \fBmount --make-rslave\fP |
||||
-after \fBunshare --mount\fP to make sure that mountpoints in the new namespace |
||||
-are really unshared from parental namespace. |
||||
+shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP or |
||||
+\fBfindmnt -o+PROPAGATION\fP for the \fBshared\fP flags). |
||||
+.sp |
||||
+.B unshare |
||||
+automatically sets propagation to \fBprivate\fP |
||||
+in the new mount namespace to make sure that the new namespace is really |
||||
+unshared. This feature is possible to disable by option \fB\-\-propagation unchanged\fP. |
||||
+Note that \fBprivate\fP is the kernel default. |
||||
.TP |
||||
.BR "UTS namespace" |
||||
Setting hostname or domainname will not affect the rest of the system. |
||||
@@ -40,13 +39,14 @@ sockets, etc. (\fBCLONE_NEWNET\fP flag) |
||||
.BR "pid namespace" |
||||
Children will have a distinct set of PID to process mappings from their parent. |
||||
(\fBCLONE_NEWPID\fP flag) |
||||
+.TP |
||||
+.BR "user namespace" |
||||
+The process will have a distinct set of UIDs, GIDs and capabilities. |
||||
+(\fBCLONE_NEWUSER\fP flag) |
||||
.PP |
||||
See \fBclone\fR(2) for the exact semantics of the flags. |
||||
.SH OPTIONS |
||||
.TP |
||||
-.BR \-h , " \-\-help" |
||||
-Display help text and exit. |
||||
-.TP |
||||
.BR \-i , " \-\-ipc" |
||||
Unshare the IPC namespace. |
||||
.TP |
||||
@@ -63,16 +63,68 @@ See also the \fB--fork\fP and \fB--mount |
||||
.BR \-u , " \-\-uts" |
||||
Unshare the UTS namespace. |
||||
.TP |
||||
+.BR \-U , " \-\-user" |
||||
+Unshare the user namespace. |
||||
+.TP |
||||
.BR \-f , " \-\-fork" |
||||
Fork the specified \fIprogram\fR as a child process of \fBunshare\fR rather than |
||||
running it directly. This is useful when creating a new pid namespace. |
||||
.TP |
||||
-.BR \-\-mount-proc "[=\fImountpoint\fP]" |
||||
-Just before running the program, mount the proc filesystem at the \fImountpoint\fP |
||||
+.BR \-\-mount\-proc "[=\fImountpoint\fP]" |
||||
+Just before running the program, mount the proc filesystem at \fImountpoint\fP |
||||
(default is /proc). This is useful when creating a new pid namespace. It also |
||||
implies creating a new mount namespace since the /proc mount would otherwise |
||||
-mess up existing programs on the system. The new proc filesystem is explicitly |
||||
+mess up existing programs on the system. The new proc filesystem is explicitly |
||||
mounted as private (by MS_PRIVATE|MS_REC). |
||||
+.TP |
||||
+.BR \-r , " \-\-map\-root\-user" |
||||
+Run the program only after the current effective user and group IDs have been mapped to |
||||
+the superuser UID and GID in the newly created user namespace. This makes it possible to |
||||
+conveniently gain capabilities needed to manage various aspects of the newly created |
||||
+namespaces (such as configuring interfaces in the network namespace or mounting filesystems in |
||||
+the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support |
||||
+more sophisticated use cases, such as mapping multiple ranges of UIDs and GIDs. |
||||
+This option implies --setgroups=deny. |
||||
+.TP |
||||
+.BR "\-\-propagation \fIprivate|shared|slave|unchanged\fP" |
||||
+Recursively sets mount propagation flag in the new mount namespace. The default |
||||
+is to set the propagation to \fIprivate\fP, this feature is possible to disable |
||||
+by \fIunchanged\fP argument. The options is silently ignored when mount namespace (\fB\-\-mount\fP) |
||||
+is not requested. |
||||
+.TP |
||||
+.BR "\-\-setgroups \fIallow|deny\fP" |
||||
+Allow or deny |
||||
+.BR setgroups (2) |
||||
+syscall in user namespaces. |
||||
+ |
||||
+.BR setgroups(2) |
||||
+is only callable with CAP_SETGID and CAP_SETGID in a user |
||||
+namespace (since Linux 3.19) does not give you permission to call setgroups(2) |
||||
+until after GID map has been set. The GID map is writable by root when |
||||
+.BR setgroups(2) |
||||
+is enabled and GID map becomes writable by unprivileged processes when |
||||
+.BR setgroups(2) |
||||
+is permanently disabled. |
||||
+.TP |
||||
+.BR \-V , " \-\-version" |
||||
+Display version information and exit. |
||||
+.TP |
||||
+.BR \-h , " \-\-help" |
||||
+Display help text and exit. |
||||
+.SH EXAMPLES |
||||
+.TP |
||||
+.B # unshare --fork --pid --mount-proc readlink /proc/self |
||||
+.TQ |
||||
+1 |
||||
+.br |
||||
+Establish a PID namespace, ensure we're PID 1 in it against newly mounted |
||||
+procfs instance. |
||||
+.TP |
||||
+.B $ unshare --map-root-user --user sh -c whoami |
||||
+.TQ |
||||
+root |
||||
+.br |
||||
+Establish a user namespace as an unprivileged user with a root user within it. |
||||
.SH SEE ALSO |
||||
.BR unshare (2), |
||||
.BR clone (2), |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.c.kzak util-linux-2.23.2/sys-utils/unshare.c |
||||
--- util-linux-2.23.2/sys-utils/unshare.c.kzak 2015-06-26 09:58:39.484633521 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.c 2015-06-26 09:58:51.673541033 +0200 |
||||
@@ -32,19 +32,117 @@ |
||||
|
||||
#include "nls.h" |
||||
#include "c.h" |
||||
+#include "closestream.h" |
||||
#include "namespace.h" |
||||
#include "exec_shell.h" |
||||
#include "xalloc.h" |
||||
#include "pathnames.h" |
||||
+#include "all-io.h" |
||||
|
||||
+/* 'private' is kernel default */ |
||||
+#define UNSHARE_PROPAGATION_DEFAULT (MS_REC | MS_PRIVATE) |
||||
+ |
||||
+enum { |
||||
+ SETGROUPS_NONE = -1, |
||||
+ SETGROUPS_DENY = 0, |
||||
+ SETGROUPS_ALLOW = 1, |
||||
+}; |
||||
+ |
||||
+static const char *setgroups_strings[] = |
||||
+{ |
||||
+ [SETGROUPS_DENY] = "deny", |
||||
+ [SETGROUPS_ALLOW] = "allow" |
||||
+}; |
||||
+ |
||||
+static int setgroups_str2id(const char *str) |
||||
+{ |
||||
+ size_t i; |
||||
+ |
||||
+ for (i = 0; i < ARRAY_SIZE(setgroups_strings); i++) |
||||
+ if (strcmp(str, setgroups_strings[i]) == 0) |
||||
+ return i; |
||||
+ |
||||
+ errx(EXIT_FAILURE, _("unsupported --setgroups argument '%s'"), str); |
||||
+} |
||||
+ |
||||
+static void setgroups_control(int action) |
||||
+{ |
||||
+ const char *file = _PATH_PROC_SETGROUPS; |
||||
+ const char *cmd; |
||||
+ int fd; |
||||
+ |
||||
+ if (action < 0 || (size_t) action >= ARRAY_SIZE(setgroups_strings)) |
||||
+ return; |
||||
+ cmd = setgroups_strings[action]; |
||||
+ |
||||
+ fd = open(file, O_WRONLY); |
||||
+ if (fd < 0) { |
||||
+ if (errno == ENOENT) |
||||
+ return; |
||||
+ err(EXIT_FAILURE, _("cannot open %s"), file); |
||||
+ } |
||||
+ |
||||
+ if (write_all(fd, cmd, strlen(cmd))) |
||||
+ err(EXIT_FAILURE, _("write failed %s"), file); |
||||
+ close(fd); |
||||
+} |
||||
+ |
||||
+static void map_id(const char *file, uint32_t from, uint32_t to) |
||||
+{ |
||||
+ char *buf; |
||||
+ int fd; |
||||
+ |
||||
+ fd = open(file, O_WRONLY); |
||||
+ if (fd < 0) |
||||
+ err(EXIT_FAILURE, _("cannot open %s"), file); |
||||
+ |
||||
+ xasprintf(&buf, "%u %u 1", from, to); |
||||
+ if (write_all(fd, buf, strlen(buf))) |
||||
+ err(EXIT_FAILURE, _("write failed %s"), file); |
||||
+ free(buf); |
||||
+ close(fd); |
||||
+} |
||||
+ |
||||
+static unsigned long parse_propagation(const char *str) |
||||
+{ |
||||
+ size_t i; |
||||
+ static const struct prop_opts { |
||||
+ const char *name; |
||||
+ unsigned long flag; |
||||
+ } opts[] = { |
||||
+ { "slave", MS_REC | MS_SLAVE }, |
||||
+ { "private", MS_REC | MS_PRIVATE }, |
||||
+ { "shared", MS_REC | MS_SHARED }, |
||||
+ { "unchanged", 0 } |
||||
+ }; |
||||
+ |
||||
+ for (i = 0; i < ARRAY_SIZE(opts); i++) { |
||||
+ if (strcmp(opts[i].name, str) == 0) |
||||
+ return opts[i].flag; |
||||
+ } |
||||
+ |
||||
+ errx(EXIT_FAILURE, _("unsupported propagation mode: %s"), str); |
||||
+} |
||||
+ |
||||
+static void set_propagation(unsigned long flags) |
||||
+{ |
||||
+ if (flags == 0) |
||||
+ return; |
||||
+ |
||||
+ if (mount("none", "/", NULL, flags, NULL) != 0) |
||||
+ err(EXIT_FAILURE, _("cannot change root filesystem propagation")); |
||||
+} |
||||
|
||||
static void usage(int status) |
||||
{ |
||||
FILE *out = status == EXIT_SUCCESS ? stdout : stderr; |
||||
|
||||
fputs(USAGE_HEADER, out); |
||||
- fprintf(out, |
||||
- _(" %s [options] <program> [args...]\n"), program_invocation_short_name); |
||||
+ fprintf(out, _(" %s [options] <program> [<argument>...]\n"), |
||||
+ program_invocation_short_name); |
||||
+ |
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Run a program with some namespaces unshared from the parent.\n"), out); |
||||
|
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -m, --mount unshare mounts namespace\n"), out); |
||||
@@ -52,8 +150,13 @@ static void usage(int status) |
||||
fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
||||
fputs(_(" -n, --net unshare network namespace\n"), out); |
||||
fputs(_(" -p, --pid unshare pid namespace\n"), out); |
||||
+ fputs(_(" -U, --user unshare user namespace\n"), out); |
||||
fputs(_(" -f, --fork fork before launching <program>\n"), out); |
||||
fputs(_(" --mount-proc[=<dir>] mount proc filesystem first (implies --mount)\n"), out); |
||||
+ fputs(_(" -r, --map-root-user map current user to root (implies --user)\n"), out); |
||||
+ fputs(_(" --propagation <slave|shared|private|unchanged>\n" |
||||
+ " modify mount propagation in mount namespace\n"), out); |
||||
+ fputs(_(" -s, --setgroups allow|deny control the setgroups syscall in user namespaces\n"), out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
@@ -66,7 +169,9 @@ static void usage(int status) |
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
enum { |
||||
- OPT_MOUNTPROC = CHAR_MAX + 1 |
||||
+ OPT_MOUNTPROC = CHAR_MAX + 1, |
||||
+ OPT_PROPAGATION, |
||||
+ OPT_SETGROUPS |
||||
}; |
||||
static const struct option longopts[] = { |
||||
{ "help", no_argument, 0, 'h' }, |
||||
@@ -76,20 +181,29 @@ int main(int argc, char *argv[]) |
||||
{ "ipc", no_argument, 0, 'i' }, |
||||
{ "net", no_argument, 0, 'n' }, |
||||
{ "pid", no_argument, 0, 'p' }, |
||||
+ { "user", no_argument, 0, 'U' }, |
||||
{ "fork", no_argument, 0, 'f' }, |
||||
{ "mount-proc", optional_argument, 0, OPT_MOUNTPROC }, |
||||
+ { "map-root-user", no_argument, 0, 'r' }, |
||||
+ { "propagation", required_argument, 0, OPT_PROPAGATION }, |
||||
+ { "setgroups", required_argument, 0, OPT_SETGROUPS }, |
||||
{ NULL, 0, 0, 0 } |
||||
}; |
||||
|
||||
+ int setgrpcmd = SETGROUPS_NONE; |
||||
int unshare_flags = 0; |
||||
- int c, forkit = 0; |
||||
+ int c, forkit = 0, maproot = 0; |
||||
const char *procmnt = NULL; |
||||
+ unsigned long propagation = UNSHARE_PROPAGATION_DEFAULT; |
||||
+ uid_t real_euid = geteuid(); |
||||
+ gid_t real_egid = getegid();; |
||||
|
||||
setlocale(LC_ALL, ""); |
||||
bindtextdomain(PACKAGE, LOCALEDIR); |
||||
textdomain(PACKAGE); |
||||
+ atexit(close_stdout); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "+fhVmuinp", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "+fhVmuinpUr", longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'f': |
||||
forkit = 1; |
||||
@@ -114,10 +228,23 @@ int main(int argc, char *argv[]) |
||||
case 'p': |
||||
unshare_flags |= CLONE_NEWPID; |
||||
break; |
||||
+ case 'U': |
||||
+ unshare_flags |= CLONE_NEWUSER; |
||||
+ break; |
||||
case OPT_MOUNTPROC: |
||||
unshare_flags |= CLONE_NEWNS; |
||||
procmnt = optarg ? optarg : "/proc"; |
||||
break; |
||||
+ case 'r': |
||||
+ unshare_flags |= CLONE_NEWUSER; |
||||
+ maproot = 1; |
||||
+ break; |
||||
+ case OPT_SETGROUPS: |
||||
+ setgrpcmd = setgroups_str2id(optarg); |
||||
+ break; |
||||
+ case OPT_PROPAGATION: |
||||
+ propagation = parse_propagation(optarg); |
||||
+ break; |
||||
default: |
||||
usage(EXIT_FAILURE); |
||||
} |
||||
@@ -146,6 +273,25 @@ int main(int argc, char *argv[]) |
||||
} |
||||
} |
||||
|
||||
+ if (maproot) { |
||||
+ if (setgrpcmd == SETGROUPS_ALLOW) |
||||
+ errx(EXIT_FAILURE, _("options --setgroups=allow and " |
||||
+ "--map-root-user are mutually exclusive")); |
||||
+ |
||||
+ /* since Linux 3.19 unprivileged writing of /proc/self/gid_map |
||||
+ * has s been disabled unless /proc/self/setgroups is written |
||||
+ * first to permanently disable the ability to call setgroups |
||||
+ * in that user namespace. */ |
||||
+ setgroups_control(SETGROUPS_DENY); |
||||
+ map_id(_PATH_PROC_UIDMAP, 0, real_euid); |
||||
+ map_id(_PATH_PROC_GIDMAP, 0, real_egid); |
||||
+ |
||||
+ } else if (setgrpcmd != SETGROUPS_NONE) |
||||
+ setgroups_control(setgrpcmd); |
||||
+ |
||||
+ if ((unshare_flags & CLONE_NEWNS) && propagation) |
||||
+ set_propagation(propagation); |
||||
+ |
||||
if (procmnt && |
||||
(mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 || |
||||
mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0)) |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
From d5b7d2912afceac3774d1aaea9e8486b54d4e9e9 Mon Sep 17 00:00:00 2001 |
||||
From: Karel Zak <kzak@redhat.com> |
||||
Date: Tue, 13 Oct 2015 12:01:29 +0200 |
||||
Subject: [PATCH] libblkid: make XFS Log visible for wipefs |
||||
|
||||
Reported-by: Peter Rajnoha <prajnoha@redhat.com> |
||||
Signed-off-by: root <root@ws.net.home> |
||||
Signed-off-by: Karel Zak <kzak@redhat.com> |
||||
--- |
||||
libblkid/src/superblocks/xfs.c | 6 ++++++ |
||||
1 file changed, 6 insertions(+) |
||||
|
||||
diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c |
||||
index a6c04a2..d13c849 100644 |
||||
--- a/libblkid/src/superblocks/xfs.c |
||||
+++ b/libblkid/src/superblocks/xfs.c |
||||
@@ -260,6 +260,12 @@ static int probe_xfs_log(blkid_probe pr, const struct blkid_idmag *mag) |
||||
|
||||
if (xlog_valid_rec_header(rhead)) { |
||||
blkid_probe_set_uuid_as(pr, rhead->h_uuid, "LOGUUID"); |
||||
+ |
||||
+ if (blkid_probe_set_magic(pr, i * 512, |
||||
+ sizeof(rhead->h_magicno), |
||||
+ (unsigned char *) &rhead->h_magicno)) |
||||
+ return 1; |
||||
+ |
||||
return 0; |
||||
} |
||||
} |
||||
-- |
||||
2.4.3 |
@ -0,0 +1,209 @@
@@ -0,0 +1,209 @@
|
||||
diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h |
||||
--- util-linux-2.23.2/include/pathnames.h.kzak 2016-03-16 17:17:02.980243390 +0100 |
||||
+++ util-linux-2.23.2/include/pathnames.h 2016-03-16 17:17:37.129015363 +0100 |
||||
@@ -36,6 +36,7 @@ |
||||
#endif |
||||
#define _PATH_MOTDFILE "/etc/motd" |
||||
#define _PATH_NOLOGIN "/etc/nologin" |
||||
+#define _PATH_VAR_NOLOGIN "/var/run/nologin" |
||||
|
||||
#define _PATH_LOGIN "/bin/login" |
||||
#define _PATH_INITTAB "/etc/inittab" |
||||
diff -up util-linux-2.23.2/login-utils/lslogins.1.kzak util-linux-2.23.2/login-utils/lslogins.1 |
||||
--- util-linux-2.23.2/login-utils/lslogins.1.kzak 2016-03-16 17:17:02.970243457 +0100 |
||||
+++ util-linux-2.23.2/login-utils/lslogins.1 2016-03-16 17:17:37.129015363 +0100 |
||||
@@ -5,7 +5,10 @@ |
||||
lslogins \- display information about known users in the system |
||||
.SH SYNOPSIS |
||||
.B lslogins |
||||
-[\fIoptions\fR] [\fB-s\fR|\fB-u\fR[=\fIUID\fR]] [\fB-g \fIgroups\fR] [\fB-l \fIlogins\fR] |
||||
+[options] |
||||
+.RB [ \-s | \-u [ =\fIUID ]] |
||||
+.RB [ \-g " \fIgroups\fR]" |
||||
+.RB [ \-l " \fIlogins\fR]" |
||||
.SH DESCRIPTION |
||||
.PP |
||||
Examine the wtmp and btmp logs, /etc/shadow (if necessary) and /etc/passwd |
||||
@@ -17,7 +20,7 @@ Mandatory arguments to long options are |
||||
.TP |
||||
\fB\-a\fR, \fB\-\-acc\-expiration\fR |
||||
Display data about the date of last password change and the account expiration |
||||
-date (see \fBshadow\fR(5) for more info). (Requires root priviliges.) |
||||
+date (see \fBshadow\fR(5) for more info). (Requires root privileges.) |
||||
.TP |
||||
\fB\-\-btmp\-file \fIpath\fP |
||||
Alternate path for btmp. |
||||
@@ -31,7 +34,7 @@ Output data in the format of NAME=VALUE. |
||||
\fB\-f\fR, \fB\-\-failed\fR |
||||
Display data about the users' last failed login attempts. |
||||
.TP |
||||
-\fB\-G\fR, \fB\-\-groups\-info\fR |
||||
+\fB\-G\fR, \fB\-\-supp\-groups\fR |
||||
Show information about groups. |
||||
.TP |
||||
\fB\-g\fR, \fB\-\-groups\fR=\fIgroups\fR |
||||
@@ -48,9 +51,6 @@ Display data containing information abou |
||||
Only show data of users with a login specified in \fIlogins\fR (user names or user |
||||
IDS). More than one login may be specified; the list has to be comma-separated. |
||||
.TP |
||||
-\fB\-m\fR, \fB\-\-supp\-groups\fR |
||||
-Show supplementary groups. |
||||
-.TP |
||||
\fB\-n\fR, \fB\-\-newline\fR |
||||
Display each piece of information on a separate line. |
||||
.TP |
||||
@@ -71,21 +71,21 @@ Display information related to login by |
||||
\fB\-r\fR, \fB\-\-raw\fR |
||||
Raw output (no columnation). |
||||
.TP |
||||
-\fB\-s\fR, \fB\-\-system\-accs\fR[=\fIthreshold\fR] |
||||
+\fB\-s\fR, \fB\-\-system\-accs\fR |
||||
Show system accounts. These are by default all accounts with a UID below 1000 |
||||
-(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534). The UID |
||||
-threshold can also be specified explicitly (necessary for some distributions that |
||||
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000). |
||||
+(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534). |
||||
+This hardcoded default maybe overwritten by parameters SYS_UID_MIN and SYS_UID_MAX in |
||||
+the file /etc/login.defs. |
||||
.TP |
||||
-\fB\-\-time-format\fR \fItype\fP |
||||
+\fB\-\-time\-format\fR \fItype\fP |
||||
Display dates in short, full or iso format. The default is short, this time |
||||
format is designed to be space efficient and human readable. |
||||
.TP |
||||
-\fB\-u\fR, \fB\-\-user\-accs\fR[=\fIthreshold\fR] |
||||
+\fB\-u\fR, \fB\-\-user\-accs\fR |
||||
Show user accounts. These are by default all accounts with UID above 1000 |
||||
-(inclusive), with the exception of either nobody or nfsnobody (UID 65534). The UID |
||||
-threshold can also be specified explicitly (necessary for some distributions that |
||||
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000). |
||||
+(inclusive), with the exception of either nobody or nfsnobody (UID 65534). |
||||
+This hardcoded default maybe overwritten by parameters UID_MIN and UID_MAX in |
||||
+the file /etc/login.defs. |
||||
.TP |
||||
\fB\-V\fR, \fB\-\-version\fR |
||||
Display version information and exit. |
||||
diff -up util-linux-2.23.2/login-utils/lslogins.c.kzak util-linux-2.23.2/login-utils/lslogins.c |
||||
--- util-linux-2.23.2/login-utils/lslogins.c.kzak 2016-03-16 17:17:02.970243457 +0100 |
||||
+++ util-linux-2.23.2/login-utils/lslogins.c 2016-03-16 17:23:47.191484521 +0100 |
||||
@@ -396,7 +396,7 @@ again: |
||||
x = snprintf(p, len, "%s,", grp->gr_name); |
||||
} |
||||
|
||||
- if (x < 0 || (size_t) x + 1 > len) { |
||||
+ if (x < 0 || (size_t) x >= len) { |
||||
size_t cur = p - res; |
||||
|
||||
maxlen *= 2; |
||||
@@ -496,21 +496,24 @@ static int parse_btmp(struct lslogins_co |
||||
static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd) |
||||
{ |
||||
size_t n = 0; |
||||
+ int ngroups = 0; |
||||
|
||||
*len = 0; |
||||
*list = NULL; |
||||
|
||||
/* first let's get a supp. group count */ |
||||
- getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len); |
||||
- if (!*len) |
||||
+ getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups); |
||||
+ if (!ngroups) |
||||
return -1; |
||||
|
||||
- *list = xcalloc(1, *len * sizeof(gid_t)); |
||||
+ *list = xcalloc(1, ngroups * sizeof(gid_t)); |
||||
|
||||
/* now for the actual list of GIDs */ |
||||
- if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len)) |
||||
+ if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups)) |
||||
return -1; |
||||
|
||||
+ *len = (size_t) ngroups; |
||||
+ |
||||
/* getgroups also returns the user's primary GID - dispose of it */ |
||||
while (n < *len) { |
||||
if ((*list)[n] == pwd->pw_gid) |
||||
@@ -852,7 +855,7 @@ static int get_user(struct lslogins_cont |
||||
const char *username) |
||||
{ |
||||
*user = get_user_info(ctl, username); |
||||
- if (!*user && errno) |
||||
+ if (!*user) |
||||
if (IS_REAL_ERRNO(errno)) |
||||
return -1; |
||||
return 0; |
||||
@@ -1193,16 +1196,18 @@ static void __attribute__((__noreturn__) |
||||
fputs(USAGE_HEADER, out); |
||||
fprintf(out, _(" %s [options]\n"), program_invocation_short_name); |
||||
|
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Display information about known users in the system.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -a, --acc-expiration display info about passwords expiration\n"), out); |
||||
fputs(_(" -c, --colon-separate display data in a format similar to /etc/passwd\n"), out); |
||||
fputs(_(" -e, --export display in an export-able output format\n"), out); |
||||
fputs(_(" -f, --failed display data about the users' last failed logins\n"), out); |
||||
- fputs(_(" -G, --groups-info display information about groups\n"), out); |
||||
+ fputs(_(" -G, --supp-groups display information about groups\n"), out); |
||||
fputs(_(" -g, --groups=<groups> display users belonging to a group in <groups>\n"), out); |
||||
fputs(_(" -L, --last show info about the users' last login sessions\n"), out); |
||||
fputs(_(" -l, --logins=<logins> display only users from <logins>\n"), out); |
||||
- fputs(_(" -m, --supp-groups display supplementary groups as well\n"), out); |
||||
fputs(_(" -n, --newline display each piece of information on a new line\n"), out); |
||||
fputs(_(" --noheadings don't print headings\n"), out); |
||||
fputs(_(" --notruncate don't truncate output\n"), out); |
||||
@@ -1226,7 +1231,7 @@ static void __attribute__((__noreturn__) |
||||
fprintf(out, " %14s %s\n", coldescs[i].name, |
||||
_(coldescs[i].help)); |
||||
|
||||
- fprintf(out, _("\nFor more details see lslogins(1).\n")); |
||||
+ fprintf(out, USAGE_MAN_TAIL("lslogins(1)")); |
||||
|
||||
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); |
||||
} |
||||
@@ -1241,8 +1246,7 @@ int main(int argc, char *argv[]) |
||||
|
||||
/* long only options. */ |
||||
enum { |
||||
- OPT_VER = CHAR_MAX + 1, |
||||
- OPT_WTMP, |
||||
+ OPT_WTMP = CHAR_MAX + 1, |
||||
OPT_BTMP, |
||||
OPT_NOTRUNC, |
||||
OPT_NOHEAD, |
||||
@@ -1300,7 +1304,7 @@ int main(int argc, char *argv[]) |
||||
add_column(columns, ncolumns++, COL_UID); |
||||
add_column(columns, ncolumns++, COL_USER); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "acfGg:hLl:no:prsuVxzZ", |
||||
+ while ((c = getopt_long(argc, argv, "acefGg:hLl:no:prsuVzZ", |
||||
longopts, NULL)) != -1) { |
||||
|
||||
err_exclusive_options(c, longopts, excl, excl_st); |
||||
@@ -1397,6 +1401,7 @@ int main(int argc, char *argv[]) |
||||
{ |
||||
size_t i; |
||||
|
||||
+ ctl->time_mode = TIME_INVALID; |
||||
for (i = 0; i < ARRAY_SIZE(timefmts); i++) { |
||||
if (strcmp(timefmts[i].name, optarg) == 0) { |
||||
ctl->time_mode = timefmts[i].val; |
||||
@@ -1404,7 +1409,7 @@ int main(int argc, char *argv[]) |
||||
} |
||||
} |
||||
if (ctl->time_mode == TIME_INVALID) |
||||
- usage(stderr); |
||||
+ errx(EXIT_FAILURE, _("unknown time format: %s"), optarg); |
||||
} |
||||
break; |
||||
case 'V': |
||||
@@ -1433,7 +1438,7 @@ int main(int argc, char *argv[]) |
||||
logins = argv[optind]; |
||||
outmode = OUT_PRETTY; |
||||
} else if (argc != optind) |
||||
- usage(stderr); |
||||
+ errx(EXIT_FAILURE, _("Only one user may be specified. Use -l for multiple users.")); |
||||
|
||||
scols_init_debug(0); |
@ -0,0 +1,459 @@
@@ -0,0 +1,459 @@
|
||||
diff -up util-linux-2.23.2/include/pathnames.h.kzak util-linux-2.23.2/include/pathnames.h |
||||
--- util-linux-2.23.2/include/pathnames.h.kzak 2016-03-16 15:17:42.648298525 +0100 |
||||
+++ util-linux-2.23.2/include/pathnames.h 2016-03-16 15:18:13.769055345 +0100 |
||||
@@ -36,6 +36,7 @@ |
||||
#endif |
||||
#define _PATH_MOTDFILE "/etc/motd" |
||||
#define _PATH_NOLOGIN "/etc/nologin" |
||||
+#define _PATH_VAR_NOLOGIN "/var/run/nologin" |
||||
|
||||
#define _PATH_LOGIN "/bin/login" |
||||
#define _PATH_INITTAB "/etc/inittab" |
||||
diff -up util-linux-2.23.2/login-utils/lslogins.1.kzak util-linux-2.23.2/login-utils/lslogins.1 |
||||
--- util-linux-2.23.2/login-utils/lslogins.1.kzak 2016-03-16 15:17:42.639298595 +0100 |
||||
+++ util-linux-2.23.2/login-utils/lslogins.1 2016-03-16 15:18:13.769055345 +0100 |
||||
@@ -5,7 +5,10 @@ |
||||
lslogins \- display information about known users in the system |
||||
.SH SYNOPSIS |
||||
.B lslogins |
||||
-[\fIoptions\fR] [\fB-s\fR|\fB-u\fR[=\fIUID\fR]] [\fB-g \fIgroups\fR] [\fB-l \fIlogins\fR] |
||||
+[options] |
||||
+.RB [ \-s | \-u [ =\fIUID ]] |
||||
+.RB [ \-g " \fIgroups\fR]" |
||||
+.RB [ \-l " \fIlogins\fR]" |
||||
.SH DESCRIPTION |
||||
.PP |
||||
Examine the wtmp and btmp logs, /etc/shadow (if necessary) and /etc/passwd |
||||
@@ -17,7 +20,7 @@ Mandatory arguments to long options are |
||||
.TP |
||||
\fB\-a\fR, \fB\-\-acc\-expiration\fR |
||||
Display data about the date of last password change and the account expiration |
||||
-date (see \fBshadow\fR(5) for more info). (Requires root priviliges.) |
||||
+date (see \fBshadow\fR(5) for more info). (Requires root privileges.) |
||||
.TP |
||||
\fB\-\-btmp\-file \fIpath\fP |
||||
Alternate path for btmp. |
||||
@@ -31,7 +34,7 @@ Output data in the format of NAME=VALUE. |
||||
\fB\-f\fR, \fB\-\-failed\fR |
||||
Display data about the users' last failed login attempts. |
||||
.TP |
||||
-\fB\-G\fR, \fB\-\-groups\-info\fR |
||||
+\fB\-G\fR, \fB\-\-supp\-groups\fR |
||||
Show information about groups. |
||||
.TP |
||||
\fB\-g\fR, \fB\-\-groups\fR=\fIgroups\fR |
||||
@@ -48,9 +51,6 @@ Display data containing information abou |
||||
Only show data of users with a login specified in \fIlogins\fR (user names or user |
||||
IDS). More than one login may be specified; the list has to be comma-separated. |
||||
.TP |
||||
-\fB\-m\fR, \fB\-\-supp\-groups\fR |
||||
-Show supplementary groups. |
||||
-.TP |
||||
\fB\-n\fR, \fB\-\-newline\fR |
||||
Display each piece of information on a separate line. |
||||
.TP |
||||
@@ -71,21 +71,21 @@ Display information related to login by |
||||
\fB\-r\fR, \fB\-\-raw\fR |
||||
Raw output (no columnation). |
||||
.TP |
||||
-\fB\-s\fR, \fB\-\-system\-accs\fR[=\fIthreshold\fR] |
||||
+\fB\-s\fR, \fB\-\-system\-accs\fR |
||||
Show system accounts. These are by default all accounts with a UID below 1000 |
||||
-(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534). The UID |
||||
-threshold can also be specified explicitly (necessary for some distributions that |
||||
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000). |
||||
+(non-inclusive), with the exception of either nobody or nfsnobody (UID 65534). |
||||
+This hardcoded default maybe overwritten by parameters SYS_UID_MIN and SYS_UID_MAX in |
||||
+the file /etc/login.defs. |
||||
.TP |
||||
-\fB\-\-time-format\fR \fItype\fP |
||||
+\fB\-\-time\-format\fR \fItype\fP |
||||
Display dates in short, full or iso format. The default is short, this time |
||||
format is designed to be space efficient and human readable. |
||||
.TP |
||||
-\fB\-u\fR, \fB\-\-user\-accs\fR[=\fIthreshold\fR] |
||||
+\fB\-u\fR, \fB\-\-user\-accs\fR |
||||
Show user accounts. These are by default all accounts with UID above 1000 |
||||
-(inclusive), with the exception of either nobody or nfsnobody (UID 65534). The UID |
||||
-threshold can also be specified explicitly (necessary for some distributions that |
||||
-allocate UIDs starting from 100, 500 - or an entirely different value - rather than 1000). |
||||
+(inclusive), with the exception of either nobody or nfsnobody (UID 65534). |
||||
+This hardcoded default maybe overwritten by parameters UID_MIN and UID_MAX in |
||||
+the file /etc/login.defs. |
||||
.TP |
||||
\fB\-V\fR, \fB\-\-version\fR |
||||
Display version information and exit. |
||||
diff -up util-linux-2.23.2/login-utils/lslogins.c.kzak util-linux-2.23.2/login-utils/lslogins.c |
||||
--- util-linux-2.23.2/login-utils/lslogins.c.kzak 2016-03-16 15:17:42.639298595 +0100 |
||||
+++ util-linux-2.23.2/login-utils/lslogins.c 2016-03-16 15:22:49.845899268 +0100 |
||||
@@ -144,6 +144,7 @@ enum { |
||||
TIME_SHORT, |
||||
TIME_FULL, |
||||
TIME_ISO, |
||||
+ TIME_ISO_SHORT, |
||||
}; |
||||
|
||||
/* |
||||
@@ -350,6 +351,9 @@ static char *make_time(int mode, time_t |
||||
case TIME_ISO: |
||||
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", &tm); |
||||
break; |
||||
+ case TIME_ISO_SHORT: |
||||
+ strftime(buf, sizeof(buf), "%Y-%m-%d", &tm); |
||||
+ break; |
||||
default: |
||||
errx(EXIT_FAILURE, _("unsupported time type")); |
||||
} |
||||
@@ -396,7 +400,7 @@ again: |
||||
x = snprintf(p, len, "%s,", grp->gr_name); |
||||
} |
||||
|
||||
- if (x < 0 || (size_t) x + 1 > len) { |
||||
+ if (x < 0 || (size_t) x >= len) { |
||||
size_t cur = p - res; |
||||
|
||||
maxlen *= 2; |
||||
@@ -496,21 +500,24 @@ static int parse_btmp(struct lslogins_co |
||||
static int get_sgroups(gid_t **list, size_t *len, struct passwd *pwd) |
||||
{ |
||||
size_t n = 0; |
||||
+ int ngroups = 0; |
||||
|
||||
*len = 0; |
||||
*list = NULL; |
||||
|
||||
/* first let's get a supp. group count */ |
||||
- getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len); |
||||
- if (!*len) |
||||
+ getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups); |
||||
+ if (!ngroups) |
||||
return -1; |
||||
|
||||
- *list = xcalloc(1, *len * sizeof(gid_t)); |
||||
+ *list = xcalloc(1, ngroups * sizeof(gid_t)); |
||||
|
||||
/* now for the actual list of GIDs */ |
||||
- if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, (int *) len)) |
||||
+ if (-1 == getgrouplist(pwd->pw_name, pwd->pw_gid, *list, &ngroups)) |
||||
return -1; |
||||
|
||||
+ *len = (size_t) ngroups; |
||||
+ |
||||
/* getgroups also returns the user's primary GID - dispose of it */ |
||||
while (n < *len) { |
||||
if ((*list)[n] == pwd->pw_gid) |
||||
@@ -520,6 +527,7 @@ static int get_sgroups(gid_t **list, siz |
||||
|
||||
if (*len) |
||||
(*list)[n] = (*list)[--(*len)]; |
||||
+ |
||||
return 0; |
||||
} |
||||
|
||||
@@ -685,8 +693,8 @@ static struct lslogins_user *get_user_in |
||||
if (strstr(pwd->pw_shell, "nologin")) |
||||
user->nologin = 1; |
||||
else if (pwd->pw_uid) |
||||
- user->nologin = access("/etc/nologin", F_OK) == 0 || |
||||
- access("/var/run/nologin", F_OK) == 0; |
||||
+ user->nologin = access(_PATH_NOLOGIN, F_OK) == 0 || |
||||
+ access(_PATH_VAR_NOLOGIN, F_OK) == 0; |
||||
break; |
||||
case COL_PWD_WARN: |
||||
if (shadow && shadow->sp_warn >= 0) |
||||
@@ -694,7 +702,8 @@ static struct lslogins_user *get_user_in |
||||
break; |
||||
case COL_PWD_EXPIR: |
||||
if (shadow && shadow->sp_expire >= 0) |
||||
- user->pwd_expire = make_time(TIME_SHORT, |
||||
+ user->pwd_expire = make_time(ctl->time_mode == TIME_ISO ? |
||||
+ TIME_ISO_SHORT : ctl->time_mode, |
||||
shadow->sp_expire * 86400); |
||||
break; |
||||
case COL_PWD_CTIME: |
||||
@@ -702,7 +711,8 @@ static struct lslogins_user *get_user_in |
||||
* (especially in non-GMT timezones) would only serve |
||||
* to confuse */ |
||||
if (shadow) |
||||
- user->pwd_ctime = make_time(TIME_SHORT, |
||||
+ user->pwd_ctime = make_time(ctl->time_mode == TIME_ISO ? |
||||
+ TIME_ISO_SHORT : ctl->time_mode, |
||||
shadow->sp_lstchg * 86400); |
||||
break; |
||||
case COL_PWD_CTIME_MIN: |
||||
@@ -852,7 +862,7 @@ static int get_user(struct lslogins_cont |
||||
const char *username) |
||||
{ |
||||
*user = get_user_info(ctl, username); |
||||
- if (!*user && errno) |
||||
+ if (!*user) |
||||
if (IS_REAL_ERRNO(errno)) |
||||
return -1; |
||||
return 0; |
||||
@@ -887,33 +897,33 @@ static int create_usertree(struct lslogi |
||||
|
||||
static struct libscols_table *setup_table(struct lslogins_control *ctl) |
||||
{ |
||||
- struct libscols_table *tb = scols_new_table(); |
||||
+ struct libscols_table *table = scols_new_table(); |
||||
int n = 0; |
||||
|
||||
- if (!tb) |
||||
+ if (!table) |
||||
errx(EXIT_FAILURE, _("failed to initialize output table")); |
||||
if (ctl->noheadings) |
||||
- scols_table_enable_noheadings(tb, 1); |
||||
+ scols_table_enable_noheadings(table, 1); |
||||
|
||||
switch(outmode) { |
||||
case OUT_COLON: |
||||
- scols_table_enable_raw(tb, 1); |
||||
- scols_table_set_column_separator(tb, ":"); |
||||
+ scols_table_enable_raw(table, 1); |
||||
+ scols_table_set_column_separator(table, ":"); |
||||
break; |
||||
case OUT_NEWLINE: |
||||
- scols_table_set_column_separator(tb, "\n"); |
||||
+ scols_table_set_column_separator(table, "\n"); |
||||
/* fallthrough */ |
||||
case OUT_EXPORT: |
||||
- scols_table_enable_export(tb, 1); |
||||
+ scols_table_enable_export(table, 1); |
||||
break; |
||||
case OUT_NUL: |
||||
- scols_table_set_line_separator(tb, "\0"); |
||||
+ scols_table_set_line_separator(table, "\0"); |
||||
/* fallthrough */ |
||||
case OUT_RAW: |
||||
- scols_table_enable_raw(tb, 1); |
||||
+ scols_table_enable_raw(table, 1); |
||||
break; |
||||
case OUT_PRETTY: |
||||
- scols_table_enable_noheadings(tb, 1); |
||||
+ scols_table_enable_noheadings(table, 1); |
||||
default: |
||||
break; |
||||
} |
||||
@@ -924,7 +934,7 @@ static struct libscols_table *setup_tabl |
||||
if (ctl->notrunc) |
||||
flags &= ~SCOLS_FL_TRUNC; |
||||
|
||||
- if (!scols_table_new_column(tb, |
||||
+ if (!scols_table_new_column(table, |
||||
coldescs[columns[n]].name, |
||||
coldescs[columns[n]].whint, |
||||
flags)) |
||||
@@ -932,9 +942,9 @@ static struct libscols_table *setup_tabl |
||||
++n; |
||||
} |
||||
|
||||
- return tb; |
||||
+ return table; |
||||
fail: |
||||
- scols_unref_table(tb); |
||||
+ scols_unref_table(table); |
||||
return NULL; |
||||
} |
||||
|
||||
@@ -1050,10 +1060,10 @@ static void fill_table(const void *u, co |
||||
return; |
||||
} |
||||
#ifdef HAVE_LIBSYSTEMD |
||||
-static void print_journal_tail(const char *journal_path, uid_t uid, size_t len) |
||||
+static void print_journal_tail(const char *journal_path, uid_t uid, size_t len, int time_mode) |
||||
{ |
||||
sd_journal *j; |
||||
- char *match, *buf; |
||||
+ char *match, *timestamp; |
||||
uint64_t x; |
||||
time_t t; |
||||
const char *identifier, *pid, *message; |
||||
@@ -1064,7 +1074,6 @@ static void print_journal_tail(const cha |
||||
else |
||||
sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); |
||||
|
||||
- buf = xmalloc(sizeof(char) * 16); |
||||
xasprintf(&match, "_UID=%d", uid); |
||||
|
||||
sd_journal_add_match(j, match, 0); |
||||
@@ -1074,37 +1083,35 @@ static void print_journal_tail(const cha |
||||
do { |
||||
if (0 > sd_journal_get_data(j, "SYSLOG_IDENTIFIER", |
||||
(const void **) &identifier, &identifier_len)) |
||||
- return; |
||||
+ goto done; |
||||
if (0 > sd_journal_get_data(j, "_PID", |
||||
(const void **) &pid, &pid_len)) |
||||
- return; |
||||
+ goto done; |
||||
if (0 > sd_journal_get_data(j, "MESSAGE", |
||||
(const void **) &message, &message_len)) |
||||
- return; |
||||
+ goto done; |
||||
|
||||
sd_journal_get_realtime_usec(j, &x); |
||||
t = x / 1000000; |
||||
- strftime(buf, 16, "%b %d %H:%M:%S", localtime(&t)); |
||||
- |
||||
- fprintf(stdout, "%s", buf); |
||||
- |
||||
+ timestamp = make_time(time_mode, t); |
||||
+ /* Get rid of journal entry field identifiers */ |
||||
identifier = strchr(identifier, '=') + 1; |
||||
- pid = strchr(pid, '=') + 1 ; |
||||
+ pid = strchr(pid, '=') + 1; |
||||
message = strchr(message, '=') + 1; |
||||
|
||||
- fprintf(stdout, " %s", identifier); |
||||
- fprintf(stdout, "[%s]:", pid); |
||||
- fprintf(stdout, "%s\n", message); |
||||
+ fprintf(stdout, "%s %s[%s]: %s\n", timestamp, identifier, pid, |
||||
+ message); |
||||
+ free(timestamp); |
||||
} while (sd_journal_next(j)); |
||||
|
||||
- free(buf); |
||||
+done: |
||||
free(match); |
||||
sd_journal_flush_matches(j); |
||||
sd_journal_close(j); |
||||
} |
||||
#endif |
||||
|
||||
-static int print_pretty(struct libscols_table *tb) |
||||
+static int print_pretty(struct libscols_table *table) |
||||
{ |
||||
struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD); |
||||
struct libscols_column *col; |
||||
@@ -1113,8 +1120,8 @@ static int print_pretty(struct libscols_ |
||||
const char *hstr, *dstr; |
||||
int n = 0; |
||||
|
||||
- ln = scols_table_get_line(tb, 0); |
||||
- while (!scols_table_next_column(tb, itr, &col)) { |
||||
+ ln = scols_table_get_line(table, 0); |
||||
+ while (!scols_table_next_column(table, itr, &col)) { |
||||
|
||||
data = scols_line_get_cell(ln, n); |
||||
|
||||
@@ -1142,7 +1149,7 @@ static int print_user_table(struct lslog |
||||
print_pretty(tb); |
||||
#ifdef HAVE_LIBSYSTEMD |
||||
fprintf(stdout, _("\nLast logs:\n")); |
||||
- print_journal_tail(ctl->journal_path, ctl->uid, 3); |
||||
+ print_journal_tail(ctl->journal_path, ctl->uid, 3, ctl->time_mode); |
||||
fputc('\n', stdout); |
||||
#endif |
||||
} else |
||||
@@ -1175,16 +1182,25 @@ static void free_user(void *f) |
||||
free(u); |
||||
} |
||||
|
||||
-struct lslogins_timefmt { |
||||
- const char *name; |
||||
- int val; |
||||
-}; |
||||
+static int parse_time_mode(const char *optarg) |
||||
+{ |
||||
+ struct lslogins_timefmt { |
||||
+ const char *name; |
||||
+ const int val; |
||||
+ }; |
||||
+ static const struct lslogins_timefmt timefmts[] = { |
||||
+ {"iso", TIME_ISO}, |
||||
+ {"full", TIME_FULL}, |
||||
+ {"short", TIME_SHORT}, |
||||
+ }; |
||||
+ size_t i; |
||||
|
||||
-static struct lslogins_timefmt timefmts[] = { |
||||
- { "short", TIME_SHORT }, |
||||
- { "full", TIME_FULL }, |
||||
- { "iso", TIME_ISO }, |
||||
-}; |
||||
+ for (i = 0; i < ARRAY_SIZE(timefmts); i++) { |
||||
+ if (strcmp(timefmts[i].name, optarg) == 0) |
||||
+ return timefmts[i].val; |
||||
+ } |
||||
+ errx(EXIT_FAILURE, _("unknown time format: %s"), optarg); |
||||
+} |
||||
|
||||
static void __attribute__((__noreturn__)) usage(FILE *out) |
||||
{ |
||||
@@ -1193,16 +1209,18 @@ static void __attribute__((__noreturn__) |
||||
fputs(USAGE_HEADER, out); |
||||
fprintf(out, _(" %s [options]\n"), program_invocation_short_name); |
||||
|
||||
+ fputs(USAGE_SEPARATOR, out); |
||||
+ fputs(_("Display information about known users in the system.\n"), out); |
||||
+ |
||||
fputs(USAGE_OPTIONS, out); |
||||
fputs(_(" -a, --acc-expiration display info about passwords expiration\n"), out); |
||||
fputs(_(" -c, --colon-separate display data in a format similar to /etc/passwd\n"), out); |
||||
fputs(_(" -e, --export display in an export-able output format\n"), out); |
||||
fputs(_(" -f, --failed display data about the users' last failed logins\n"), out); |
||||
- fputs(_(" -G, --groups-info display information about groups\n"), out); |
||||
+ fputs(_(" -G, --supp-groups display information about groups\n"), out); |
||||
fputs(_(" -g, --groups=<groups> display users belonging to a group in <groups>\n"), out); |
||||
fputs(_(" -L, --last show info about the users' last login sessions\n"), out); |
||||
fputs(_(" -l, --logins=<logins> display only users from <logins>\n"), out); |
||||
- fputs(_(" -m, --supp-groups display supplementary groups as well\n"), out); |
||||
fputs(_(" -n, --newline display each piece of information on a new line\n"), out); |
||||
fputs(_(" --noheadings don't print headings\n"), out); |
||||
fputs(_(" --notruncate don't truncate output\n"), out); |
||||
@@ -1226,7 +1244,7 @@ static void __attribute__((__noreturn__) |
||||
fprintf(out, " %14s %s\n", coldescs[i].name, |
||||
_(coldescs[i].help)); |
||||
|
||||
- fprintf(out, _("\nFor more details see lslogins(1).\n")); |
||||
+ fprintf(out, USAGE_MAN_TAIL("lslogins(1)")); |
||||
|
||||
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); |
||||
} |
||||
@@ -1241,8 +1259,7 @@ int main(int argc, char *argv[]) |
||||
|
||||
/* long only options. */ |
||||
enum { |
||||
- OPT_VER = CHAR_MAX + 1, |
||||
- OPT_WTMP, |
||||
+ OPT_WTMP = CHAR_MAX + 1, |
||||
OPT_BTMP, |
||||
OPT_NOTRUNC, |
||||
OPT_NOHEAD, |
||||
@@ -1300,7 +1317,7 @@ int main(int argc, char *argv[]) |
||||
add_column(columns, ncolumns++, COL_UID); |
||||
add_column(columns, ncolumns++, COL_USER); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "acfGg:hLl:no:prsuVxzZ", |
||||
+ while ((c = getopt_long(argc, argv, "acefGg:hLl:no:prsuVzZ", |
||||
longopts, NULL)) != -1) { |
||||
|
||||
err_exclusive_options(c, longopts, excl, excl_st); |
||||
@@ -1394,18 +1411,7 @@ int main(int argc, char *argv[]) |
||||
ctl->noheadings = 1; |
||||
break; |
||||
case OPT_TIME_FMT: |
||||
- { |
||||
- size_t i; |
||||
- |
||||
- for (i = 0; i < ARRAY_SIZE(timefmts); i++) { |
||||
- if (strcmp(timefmts[i].name, optarg) == 0) { |
||||
- ctl->time_mode = timefmts[i].val; |
||||
- break; |
||||
- } |
||||
- } |
||||
- if (ctl->time_mode == TIME_INVALID) |
||||
- usage(stderr); |
||||
- } |
||||
+ ctl->time_mode = parse_time_mode(optarg); |
||||
break; |
||||
case 'V': |
||||
printf(UTIL_LINUX_VERSION); |
||||
@@ -1433,7 +1439,7 @@ int main(int argc, char *argv[]) |
||||
logins = argv[optind]; |
||||
outmode = OUT_PRETTY; |
||||
} else if (argc != optind) |
||||
- usage(stderr); |
||||
+ errx(EXIT_FAILURE, _("Only one user may be specified. Use -l for multiple users.")); |
||||
|
||||
scols_init_debug(0); |
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
.\" $OpenBSD: nologin.8,v 1.8 1999/06/04 02:45:19 aaron Exp $ |
||||
.\" $NetBSD: nologin.8,v 1.3 1995/03/18 14:59:09 cgd Exp $ |
||||
.\" |
||||
.\" Copyright (c) 1993 |
||||
.\" The Regents of the University of California. All rights reserved. |
||||
.\" |
||||
.\" Redistribution and use in source and binary forms, with or without |
||||
.\" modification, are permitted provided that the following conditions |
||||
.\" are met: |
||||
.\" 1. Redistributions of source code must retain the above copyright |
||||
.\" notice, this list of conditions and the following disclaimer. |
||||
.\" 2. Redistributions in binary form must reproduce the above copyright |
||||
.\" notice, this list of conditions and the following disclaimer in the |
||||
.\" documentation and/or other materials provided with the distribution. |
||||
.\" 3. All advertising materials mentioning features or use of this software |
||||
.\" must display the following acknowledgement: |
||||
.\" This product includes software developed by the University of |
||||
.\" California, Berkeley and its contributors. |
||||
.\" 4. Neither the name of the University nor the names of its contributors |
||||
.\" may be used to endorse or promote products derived from this software |
||||
.\" without specific prior written permission. |
||||
.\" |
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||
.\" SUCH DAMAGE. |
||||
.\" |
||||
.\" @(#)nologin.8 8.1 (Berkeley) 6/19/93 |
||||
.\" |
||||
.Dd February 15, 1997 |
||||
.Dt NOLOGIN 8 |
||||
.Os |
||||
.Sh NAME |
||||
.Nm nologin |
||||
.Nd politely refuse a login |
||||
.Sh SYNOPSIS |
||||
.Nm nologin |
||||
.Sh DESCRIPTION |
||||
.Nm |
||||
displays a message that an account is not available and |
||||
exits non-zero. |
||||
It is intended as a replacement shell field for accounts that |
||||
have been disabled. |
||||
.Pp |
||||
If the file |
||||
.Pa /etc/nologin.txt |
||||
exists, |
||||
.Nm |
||||
displays its contents to the user instead of the default message. |
||||
.Sh SEE ALSO |
||||
.Xr login 1 |
||||
.Sh HISTORY |
||||
The |
||||
.Nm |
||||
command appeared in |
||||
.Bx 4.4 . |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
/* $OpenBSD: nologin.c,v 1.2 1997/04/04 16:51:37 millert Exp $ */ |
||||
|
||||
/* |
||||
* Copyright (c) 1997, Jason Downs. All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions |
||||
* are met: |
||||
* 1. Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* 2. Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS |
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||
* SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include <sys/types.h> |
||||
#include <fcntl.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
#include <stdlib.h> |
||||
|
||||
/* Distinctly different from _PATH_NOLOGIN. */ |
||||
#define _PATH_NOLOGIN_TXT "/etc/nologin.txt" |
||||
|
||||
#define DEFAULT_MESG "This account is currently not available.\n" |
||||
|
||||
/*ARGSUSED*/ |
||||
int main(argc, argv) |
||||
int argc; |
||||
char *argv[]; |
||||
{ |
||||
int nfd, nrd; |
||||
char nbuf[128]; |
||||
|
||||
nfd = open(_PATH_NOLOGIN_TXT, O_RDONLY); |
||||
if (nfd < 0) { |
||||
write(STDOUT_FILENO, DEFAULT_MESG, strlen(DEFAULT_MESG)); |
||||
exit (1); |
||||
} |
||||
|
||||
while ((nrd = read(nfd, nbuf, sizeof(nbuf))) > 0) |
||||
write(STDOUT_FILENO, nbuf, nrd); |
||||
close (nfd); |
||||
|
||||
exit (1); |
||||
} |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.1.kzak util-linux-2.23.2/sys-utils/nsenter.1 |
||||
--- util-linux-2.23.2/sys-utils/nsenter.1.kzak 2014-03-12 12:39:19.283577293 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.1 2014-03-12 12:42:08.930336415 +0100 |
||||
@@ -47,12 +47,7 @@ flag). |
||||
will fork by default if changing the PID namespace, so that the new program |
||||
and its children share the same PID namespace and are visible to each other. |
||||
If \-\-no\-fork is used, the new program will be exec'ed without forking. |
||||
-.TP |
||||
-.B user namespace |
||||
-process will have distinct set of UIDs, GIDs and capabilities |
||||
-.RB ( CLONE_\:NEWUSER |
||||
-flag). |
||||
-.TP |
||||
+.PP |
||||
See the |
||||
.BR clone (2) |
||||
for exact semantics of the flags. |
||||
@@ -88,9 +83,6 @@ the network namespace |
||||
/proc/\fIpid\fR/ns/pid |
||||
the PID namespace |
||||
.TP |
||||
-/proc/\fIpid\fR/ns/user |
||||
-the user namespace |
||||
-.TP |
||||
/proc/\fIpid\fR/root |
||||
the root directory |
||||
.TP |
||||
@@ -124,11 +116,6 @@ Enter the PID namespace. If no file is |
||||
the target process. If file is specified enter the PID namespace specified by |
||||
file. |
||||
.TP |
||||
-\fB\-U\fR, \fB\-\-user\fR [\fIfile\fR] |
||||
-Enter the user namespace. If no file is specified enter the user namespace of |
||||
-the target process. If file is specified enter the user namespace specified by |
||||
-file. |
||||
-.TP |
||||
\fB\-r\fR, \fB\-\-root\fR [\fIdirectory\fR] |
||||
Set the root directory. If no directory is specified set the root directory to |
||||
the root directory of the target process. If directory is specified set the |
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.c.kzak util-linux-2.23.2/sys-utils/nsenter.c |
||||
--- util-linux-2.23.2/sys-utils/nsenter.c.kzak 2014-03-12 12:39:10.402485179 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.c 2014-03-12 12:44:07.986570461 +0100 |
||||
@@ -42,12 +42,7 @@ static struct namespace_file { |
||||
int fd; |
||||
} namespace_files[] = { |
||||
/* Careful the order is significant in this array. |
||||
- * |
||||
- * The user namespace comes first, so that it is entered |
||||
- * first. This gives an unprivileged user the potential to |
||||
- * enter the other namespaces. |
||||
*/ |
||||
- { .nstype = CLONE_NEWUSER, .name = "ns/user", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWIPC, .name = "ns/ipc", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWUTS, .name = "ns/uts", .fd = -1 }, |
||||
{ .nstype = CLONE_NEWNET, .name = "ns/net", .fd = -1 }, |
||||
@@ -71,7 +66,6 @@ static void usage(int status) |
||||
fputs(_(" -i, --ipc [=<file>] enter System V IPC namespace\n"), out); |
||||
fputs(_(" -n, --net [=<file>] enter network namespace\n"), out); |
||||
fputs(_(" -p, --pid [=<file>] enter pid namespace\n"), out); |
||||
- fputs(_(" -U, --user [=<file>] enter user namespace\n"), out); |
||||
fputs(_(" -r, --root [=<dir>] set the root directory\n"), out); |
||||
fputs(_(" -w, --wd [=<dir>] set the working directory\n"), out); |
||||
fputs(_(" -F, --no-fork do not fork before exec'ing <program>\n"), out); |
||||
@@ -168,7 +162,6 @@ int main(int argc, char *argv[]) |
||||
{ "ipc", optional_argument, NULL, 'i' }, |
||||
{ "net", optional_argument, NULL, 'n' }, |
||||
{ "pid", optional_argument, NULL, 'p' }, |
||||
- { "user", optional_argument, NULL, 'U' }, |
||||
{ "root", optional_argument, NULL, 'r' }, |
||||
{ "wd", optional_argument, NULL, 'w' }, |
||||
{ "no-fork", no_argument, NULL, 'F' }, |
||||
@@ -186,7 +179,7 @@ int main(int argc, char *argv[]) |
||||
atexit(close_stdout); |
||||
|
||||
while ((c = |
||||
- getopt_long(argc, argv, "hVt:m::u::i::n::p::U::r::w::F", |
||||
+ getopt_long(argc, argv, "hVt:m::u::i::n::p::r::w::F", |
||||
longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'h': |
||||
@@ -228,12 +221,6 @@ int main(int argc, char *argv[]) |
||||
else |
||||
namespaces |= CLONE_NEWPID; |
||||
break; |
||||
- case 'U': |
||||
- if (optarg) |
||||
- open_namespace_fd(CLONE_NEWUSER, optarg); |
||||
- else |
||||
- namespaces |= CLONE_NEWUSER; |
||||
- break; |
||||
case 'F': |
||||
do_fork = 0; |
||||
break; |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.1.kzak util-linux-2.23.2/sys-utils/unshare.1 |
||||
--- util-linux-2.23.2/sys-utils/unshare.1.kzak 2014-03-12 12:39:41.367806340 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.1 2014-03-12 12:40:25.186260760 +0100 |
||||
@@ -34,9 +34,6 @@ etc. (\fBCLONE_NEWNET\fP flag). |
||||
.BR "pid namespace" |
||||
children will have a distinct set of pid to process mappings than their parent. |
||||
(\fBCLONE_NEWPID\fP flag). |
||||
-.TP |
||||
-.BR "user namespace" |
||||
-process will have distinct set of uids, gids and capabilities. (\fBCLONE_NEWUSER\fP flag). |
||||
.PP |
||||
See the \fBclone\fR(2) for exact semantics of the flags. |
||||
.SH OPTIONS |
||||
@@ -58,9 +55,6 @@ Unshare the network namespace. |
||||
.TP |
||||
.BR \-p , " \-\-pid" |
||||
Unshare the pid namespace. |
||||
-.TP |
||||
-.BR \-U , " \-\-user" |
||||
-Unshare the user namespace. |
||||
.SH SEE ALSO |
||||
.BR unshare (2), |
||||
.BR clone (2) |
||||
diff -up util-linux-2.23.2/sys-utils/unshare.c.kzak util-linux-2.23.2/sys-utils/unshare.c |
||||
--- util-linux-2.23.2/sys-utils/unshare.c.kzak 2014-03-12 12:39:46.385858383 +0100 |
||||
+++ util-linux-2.23.2/sys-utils/unshare.c 2014-03-12 12:44:49.955005384 +0100 |
||||
@@ -45,7 +45,6 @@ static void usage(int status) |
||||
fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
||||
fputs(_(" -n, --net unshare network namespace\n"), out); |
||||
fputs(_(" -p, --pid unshare pid namespace\n"), out); |
||||
- fputs(_(" -U, --user unshare user namespace\n"), out); |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
@@ -65,7 +64,6 @@ int main(int argc, char *argv[]) |
||||
{ "ipc", no_argument, 0, 'i' }, |
||||
{ "net", no_argument, 0, 'n' }, |
||||
{ "pid", no_argument, 0, 'p' }, |
||||
- { "user", no_argument, 0, 'U' }, |
||||
{ NULL, 0, 0, 0 } |
||||
}; |
||||
|
||||
@@ -78,7 +76,7 @@ int main(int argc, char *argv[]) |
||||
textdomain(PACKAGE); |
||||
atexit(close_stdout); |
||||
|
||||
- while ((c = getopt_long(argc, argv, "hVmuinpU", longopts, NULL)) != -1) { |
||||
+ while ((c = getopt_long(argc, argv, "hVmuinp", longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'h': |
||||
usage(EXIT_SUCCESS); |
||||
@@ -100,9 +98,6 @@ int main(int argc, char *argv[]) |
||||
case 'p': |
||||
unshare_flags |= CLONE_NEWPID; |
||||
break; |
||||
- case 'U': |
||||
- unshare_flags |= CLONE_NEWUSER; |
||||
- break; |
||||
default: |
||||
usage(EXIT_FAILURE); |
||||
} |
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am |
||||
--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak 2015-06-26 10:21:34.337221288 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/Makemodule.am 2015-06-26 10:22:18.719885983 +0200 |
||||
@@ -308,7 +308,7 @@ if BUILD_NSENTER |
||||
usrbin_exec_PROGRAMS += nsenter |
||||
dist_man_MANS += sys-utils/nsenter.1 |
||||
nsenter_SOURCES = sys-utils/nsenter.c |
||||
-nsenter_LDADD = $(LDADD) libcommon.la |
||||
+nsenter_LDADD = $(LDADD) libcommon.la $(SELINUX_LIBS) |
||||
endif |
||||
|
||||
if BUILD_HWCLOCK |
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.1.kzak util-linux-2.23.2/sys-utils/nsenter.1 |
||||
--- util-linux-2.23.2/sys-utils/nsenter.1.kzak 2015-06-26 10:14:00.947646586 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.1 2015-06-26 10:21:34.337221288 +0200 |
||||
@@ -155,6 +155,11 @@ Do not fork before exec'ing the specifie |
||||
PID namespace, \fBnsenter\fP calls \fBfork\fP before calling \fBexec\fP so that |
||||
any children will also be in the newly entered PID namespace. |
||||
.TP |
||||
+\fB\-Z\fR, \fB\-\-follow\-context\fR |
||||
+Set the SELinux security context used for executing a new process according to |
||||
+already running process specified by \fB\-\-target\fR PID. (The util-linux has |
||||
+to be compiled with SELinux support otherwise the option is unavailable.) |
||||
+.TP |
||||
\fB\-V\fR, \fB\-\-version\fR |
||||
Display version information and exit. |
||||
.TP |
||||
@@ -163,10 +168,14 @@ Display help text and exit. |
||||
.SH SEE ALSO |
||||
.BR setns (2), |
||||
.BR clone (2) |
||||
-.SH AUTHOR |
||||
-.MT ebiederm@xmission.com |
||||
+.SH AUTHORS |
||||
+.UR biederm@xmission.com |
||||
Eric Biederman |
||||
-.ME |
||||
+.UE |
||||
+.br |
||||
+.UR kzak@redhat.com |
||||
+Karel Zak |
||||
+.UE |
||||
.SH AVAILABILITY |
||||
The nsenter command is part of the util-linux package and is available from |
||||
.UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/ |
||||
diff -up util-linux-2.23.2/sys-utils/nsenter.c.kzak util-linux-2.23.2/sys-utils/nsenter.c |
||||
--- util-linux-2.23.2/sys-utils/nsenter.c.kzak 2015-06-26 10:14:00.947646586 +0200 |
||||
+++ util-linux-2.23.2/sys-utils/nsenter.c 2015-06-26 10:21:34.337221288 +0200 |
||||
@@ -30,6 +30,10 @@ |
||||
#include <sys/wait.h> |
||||
#include <grp.h> |
||||
|
||||
+#ifdef HAVE_LIBSELINUX |
||||
+# include <selinux/selinux.h> |
||||
+#endif |
||||
+ |
||||
#include "strutils.h" |
||||
#include "nls.h" |
||||
#include "c.h" |
||||
@@ -82,6 +86,9 @@ static void usage(int status) |
||||
fputs(_(" -r, --root[=<dir>] set the root directory\n"), out); |
||||
fputs(_(" -w, --wd[=<dir>] set the working directory\n"), out); |
||||
fputs(_(" -F, --no-fork do not fork before exec'ing <program>\n"), out); |
||||
+#ifdef HAVE_LIBSELINUX |
||||
+ fputs(_(" -Z, --follow-context set SELinux context according to --target PID\n"), out); |
||||
+#endif |
||||
|
||||
fputs(USAGE_SEPARATOR, out); |
||||
fputs(USAGE_HELP, out); |
||||
@@ -185,6 +192,9 @@ int main(int argc, char *argv[]) |
||||
{ "wd", optional_argument, NULL, 'w' }, |
||||
{ "no-fork", no_argument, NULL, 'F' }, |
||||
{ "preserve-credentials", no_argument, NULL, OPT_PRESERVE_CRED }, |
||||
+#ifdef HAVE_LIBSELINUX |
||||
+ { "follow-context", no_argument, NULL, 'Z' }, |
||||
+#endif |
||||
{ NULL, 0, NULL, 0 } |
||||
}; |
||||
|
||||
@@ -194,6 +204,9 @@ int main(int argc, char *argv[]) |
||||
int do_fork = -1; /* unknown yet */ |
||||
uid_t uid = 0; |
||||
gid_t gid = 0; |
||||
+#ifdef HAVE_LIBSELINUX |
||||
+ bool selinux = 0; |
||||
+#endif |
||||
|
||||
setlocale(LC_ALL, ""); |
||||
bindtextdomain(PACKAGE, LOCALEDIR); |
||||
@@ -201,7 +214,7 @@ int main(int argc, char *argv[]) |
||||
atexit(close_stdout); |
||||
|
||||
while ((c = |
||||
- getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::F", |
||||
+ getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::FZ", |
||||
longopts, NULL)) != -1) { |
||||
switch (c) { |
||||
case 'h': |
||||
@@ -275,11 +288,30 @@ int main(int argc, char *argv[]) |
||||
case OPT_PRESERVE_CRED: |
||||
preserve_cred = 1; |
||||
break; |
||||
+#ifdef HAVE_LIBSELINUX |
||||
+ case 'Z': |
||||
+ selinux = 1; |
||||
+ break; |
||||
+#endif |
||||
default: |
||||
usage(EXIT_FAILURE); |
||||
} |
||||
} |
||||
|
||||
+#ifdef HAVE_LIBSELINUX |
||||
+ if (selinux && is_selinux_enabled() > 0) { |
||||
+ char *scon = NULL; |
||||
+ |
||||
+ if (!namespace_target_pid) |
||||
+ errx(EXIT_FAILURE, _("no target PID specified for --follow-context")); |
||||
+ if (getpidcon(namespace_target_pid, &scon) < 0) |
||||
+ errx(EXIT_FAILURE, _("failed to get %d SELinux context"), |
||||
+ (int) namespace_target_pid); |
||||
+ if (setexeccon(scon) < 0) |
||||
+ errx(EXIT_FAILURE, _("failed to set exec context to '%s'"), scon); |
||||
+ freecon(scon); |
||||
+ } |
||||
+#endif |
||||
/* |
||||
* Open remaining namespace and directory descriptors. |
||||
*/ |
Loading…
Reference in new issue