basebuilder_pel7ppc64bebuilder0
7 years ago
64 changed files with 17036 additions and 17 deletions
@ -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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
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 @@ |
|||||||
|
.\" $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 @@ |
|||||||
|
/* $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 @@ |
|||||||
|
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 @@ |
|||||||
|
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