From 60b2bf187e5d30b4cd784ea61d88d3a1126de8fe Mon Sep 17 00:00:00 2001 From: Valerie Aurora Date: Thu, 29 Jul 2010 15:55:33 -0400 Subject: libblkid: remove dead code section commit 2d12ea54c70c9e6a2b77ca6f7b6a786309a22fa7 Author: Valerie Aurora Date: Thu Jul 29 12:47:35 2010 -0700 libblkid: remove dead code section (duplication of ext* constants) Signed-off-by: Valerie Aurora --- shlibs/blkid/src/superblocks/ext.c | 47 -------------------------------------- 1 file changed, 47 deletions(-) diff --git a/shlibs/blkid/src/superblocks/ext.c b/shlibs/blkid/src/superblocks/ext.c index b1bc2a8a..6dfe5283 100644 --- a/shlibs/blkid/src/superblocks/ext.c +++ b/shlibs/blkid/src/superblocks/ext.c @@ -131,53 +131,6 @@ struct ext2_super_block { #define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~EXT3_FEATURE_INCOMPAT_SUPP #define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP - -#ifdef FUCK - -/* for s_flags */ -#define EXT2_FLAGS_TEST_FILESYS 0x0004 - -/* for s_feature_compat */ -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 - -/* for s_feature_ro_compat */ -#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 -#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 -#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 - -/* for s_feature_incompat */ -#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 - -#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP -#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP - -#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED (~EXT3_FEATURE_INCOMPAT_SUPP) -#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT3_FEATURE_RO_COMPAT_SUPP) - -#endif - /* * Check to see if a filesystem is in /proc/filesystems. * Returns 1 if found, 0 if not -- cgit v1.2.3 From 5d79666f8f7563ed9904a7ce2087f430ee2702b6 Mon Sep 17 00:00:00 2001 From: Valerie Aurora Date: Tue, 3 Aug 2010 20:09:19 -0400 Subject: mount: get most recently mounted fs from /etc/mtab. I spent most of the day tracking down this subtle remount bug. I think this is the correct solution but I'd appreciate some double-checking. I suspect this bug will munge the mount options whenever you remount a file system mounted on the same mountpoint as another file system, using the mountpoint as the handle. -VAL commit c010b3a0783430e2b94f3b3dc0929ae299e383eb Author: Valerie Aurora Date: Tue Aug 3 16:32:52 2010 -0700 mount: get most recently mounted fs from /etc/mtab. In mount, when using /etc/mtab to lookup a mount entry, get the most recently mounted entry instead of the first mounted entry. You want to manipulate the most recent mount, not a covered mount. See comment to umount_one_bw(). This bug has been util-linux-ng since the first git checkin. It finally showed up on my system with the change to stop using SETLOOP_AUTOCLEAR if /etc/mtab is writable (commit af092544). If you do a remount of a file system mounted on the same dir as another file system, it will take the options from the first mount and write them out to /etc/mtab as the options to the second mount - including, in the case of a loop device, loop=/dev/loop0. Then when you umount the second mount, it grabs the line from /etc/mtab and tries to tear down the loop device, which complains because it is still in use by the first mount. Reproducible test case (on a system with writable /etc/mtab): mount -o loop,ro /tmp/ro /mnt mount -t tmpfs tmpfs /mnt mount -o remount,ro /mnt cat /etc/mtab | tail -2 Signed-off-by: Valerie Aurora --- mount/fstab.c | 18 ++++++++++++++++++ mount/fstab.h | 1 + mount/mount.c | 5 +++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/mount/fstab.c b/mount/fstab.c index 97d64a2c..bfb2e5d3 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -215,6 +215,24 @@ getmntfile (const char *name) { return NULL; } +/* + * Given the name NAME, and the place MCPREV we found it last time, + * try to find it in mtab. + */ +struct mntentchn * +getmntfilebackward (const char *name, struct mntentchn *mcprev) { + struct mntentchn *mc, *mc0; + + mc0 = mtab_head(); + if (!mcprev) + mcprev = mc0; + for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev) + if (streq(mc->m.mnt_dir, name) || + streq(mc->m.mnt_fsname, name)) + return mc; + return NULL; +} + /* * Given the directory name NAME, and the place MCPREV we found it last time, * try to find more occurrences. diff --git a/mount/fstab.h b/mount/fstab.h index 38f7bab9..e9855064 100644 --- a/mount/fstab.h +++ b/mount/fstab.h @@ -15,6 +15,7 @@ struct mntentchn { struct mntentchn *mtab_head (void); struct mntentchn *getmntfile (const char *name); +struct mntentchn *getmntfilebackward (const char *name, struct mntentchn *mcprev); struct mntentchn *getmntoptfile (const char *file); struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc); struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc); diff --git a/mount/mount.c b/mount/mount.c index 433941e1..2e819e95 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -2140,10 +2140,11 @@ getfs(const char *spec, const char *uuid, const char *label) /* * D) remount -- try /etc/mtab * Earlier mtab was tried first, but this would sometimes try the - * wrong mount in case mtab had the root device entry wrong. + * wrong mount in case mtab had the root device entry wrong. Try + * the last occurrence first, since that is the visible mount. */ if (!mc && (devname || spec)) - mc = getmntfile (devname ? devname : spec); + mc = getmntfilebackward (devname ? devname : spec, NULL); my_free(devname); return mc; -- cgit v1.2.3 From 219da9223d14aa21e4feb4fe850eb4c1691c98d8 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Fri, 30 Jul 2010 11:43:36 -0400 Subject: dmesg: fix memory leak in dmesg(1). Signed-off-by: Davidlohr Bueso --- sys-utils/dmesg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c index fd184aaf..f1a7dcb7 100644 --- a/sys-utils/dmesg.c +++ b/sys-utils/dmesg.c @@ -111,12 +111,12 @@ main(int argc, char *argv[]) { if (bufsize) { sz = bufsize + 8; - buf = (char *) malloc(sz); + buf = (char *) malloc(sz * sizeof(char)); n = klogctl(cmd, buf, sz); } else { sz = 16392; while (1) { - buf = (char *) malloc(sz); + buf = (char *) malloc(sz * sizeof(char)); n = klogctl(3, buf, sz); /* read only */ if (n != sz || sz > (1<<28)) break; @@ -147,5 +147,6 @@ main(int argc, char *argv[]) { } if (lastc != '\n') putchar('\n'); + free(buf); return 0; } -- cgit v1.2.3 From 108591d2b7860ca0b8d27d114bed1e504a31fa72 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 4 Aug 2010 11:52:41 +0200 Subject: losetup: use stdout and return 0 for --help Reported-by: Kamalesh Babulal Signed-off-by: Karel Zak --- mount/lomount.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/mount/lomount.c b/mount/lomount.c index 6130be1d..54b9f8e9 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -884,8 +884,8 @@ find_unused_loop_device (void) { #include "strtosize.h" static void -usage(void) { - fprintf(stderr, _("\nUsage:\n" +usage(FILE *f) { + fprintf(f, _("\nUsage:\n" " %1$s loop_device give info\n" " %1$s -a | --all list all used\n" " %1$s -d | --detach [ ...] delete\n" @@ -895,7 +895,7 @@ usage(void) { " %1$s [ options ] {-f|--find|loopdev} setup\n"), progname); - fprintf(stderr, _("\nOptions:\n" + fprintf(f, _("\nOptions:\n" " -e | --encryption enable data encryption with specified \n" " -h | --help this help\n" " -o | --offset start at offset into file\n" @@ -904,7 +904,8 @@ usage(void) { " -r | --read-only setup read-only loop device\n" " --show print device name (with -f )\n" " -v | --verbose verbose mode\n\n")); - exit(1); + + exit(f == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } int @@ -966,6 +967,9 @@ main(int argc, char **argv) { case 'f': find = 1; break; + case 'h': + usage(stdout); + break; case 'j': assoc = optarg; break; @@ -987,42 +991,42 @@ main(int argc, char **argv) { break; default: - usage(); + usage(stderr); } } if (argc == 1) { - usage(); + usage(stderr); } else if (delete) { if (argc < optind+1 || encryption || offset || sizelimit || capacity || find || all || showdev || assoc || ro) - usage(); + usage(stderr); } else if (find) { if (capacity || all || assoc || argc < optind || argc > optind+1) - usage(); + usage(stderr); } else if (all) { if (argc > 2) - usage(); + usage(stderr); } else if (assoc) { if (capacity || encryption || showdev || passfd || ro) - usage(); + usage(stderr); } else if (capacity) { if (argc != optind + 1 || encryption || offset || sizelimit || showdev || ro) - usage(); + usage(stderr); } else { if (argc < optind+1 || argc > optind+2) - usage(); + usage(stderr); } if (offset && strtosize(offset, &off)) { error(_("%s: invalid offset '%s' specified"), progname, offset); - usage(); + usage(stderr); } if (sizelimit && strtosize(sizelimit, &slimit)) { error(_("%s: invalid sizelimit '%s' specified"), progname, sizelimit); - usage(); + usage(stderr); } if (all) @@ -1057,7 +1061,7 @@ main(int argc, char **argv) { res = show_loop(device); else { if (passfd && sscanf(passfd, "%d", &pfd) != 1) - usage(); + usage(stderr); do { res = set_loop(device, file, off, slimit, encryption, pfd, &ro); if (res == 2 && find) { -- cgit v1.2.3 From 4c50b0b3b3bdddd8ec1871980adad0f95df7b688 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 4 Aug 2010 12:14:57 +0200 Subject: docs: mark line(1) as deprecated Signed-off-by: Karel Zak --- DEPRECATED | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/DEPRECATED b/DEPRECATED index f5202434..457fb229 100644 --- a/DEPRECATED +++ b/DEPRECATED @@ -2,27 +2,31 @@ The following is a list of commands or features that are deprecated. All deprecated utils are in maintenace mode and we keep them in source tree for backward compatibilty only. +What: line(1) command +Since: 2.19 +Why: useless, nobody uses this command, head(1) is better + +-------------------------- + What: losetup -s -When: 2.15 +Since: 2.15 Why: the option -s is in collision with the Loop-AES losetup dialect that is used in some distributions. Use the long version (--show) only. -------------------------- What: cryptoloop support in mount/losetup -When: undefined yet Why: depreciated in favor of dm-crypt. --------------------------- What: elvtune -When: undefined yet Why: useless for kernel >= 2.6.9 --------------------------- What: arch(1) command -When: 2.14 +Since: 2.14 Why: deprecated in favor of uname(1) or arch(1) from coreutils The arch(1) has been added (during 2.13 development cycle) to coreutuls -- cgit v1.2.3 From 3d9440ee18f27ed3412d3337c042834138c5b523 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 9 Aug 2010 11:32:46 +0200 Subject: cfdisk: fix n+1 bug in error message # cfdisk -Ps correctly uses 1..N range for partition numbers, unfortunately some error messages use 0..N. This is confusing. Reported-by: J B Signed-off-by: Karel Zak --- fdisk/cfdisk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c index e7955fe5..610b8471 100644 --- a/fdisk/cfdisk.c +++ b/fdisk/cfdisk.c @@ -1629,7 +1629,7 @@ fill_p_info(void) { ((bs <= sectors) ? bs : 0), 1, &errmsg)) { char *bad = _("Bad primary partition"); char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30); - sprintf(msg, "%s %d: %s", bad, i, errmsg); + sprintf(msg, "%s %d: %s", bad, i + 1, errmsg); fatal(msg, 4); } if (is_extended(buffer.p.part[i].sys_ind)) @@ -1659,7 +1659,7 @@ fill_p_info(void) { bs, 1, &errmsg)) { char *bad = _("Bad logical partition"); char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30); - sprintf(msg, "%s %d: %s", bad, i, errmsg); + sprintf(msg, "%s %d: %s", bad, i + 1, errmsg); fatal(msg, 4); } } -- cgit v1.2.3 From f9936f4dc0cd50d1040f7e855ef091db0edd1f64 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 9 Aug 2010 13:03:02 +0200 Subject: fdisk: update MBR after ID change Reported-by: Bernard Pidoux Signed-off-by: Karel Zak --- fdisk/fdisk.c | 19 +++++++++++++++---- tests/expected/fdisk/id | 5 +++++ tests/ts/fdisk/id | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 tests/expected/fdisk/id create mode 100755 tests/ts/fdisk/id diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index 6572c51d..af95bcc6 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -180,6 +180,8 @@ static int type_open = O_RDWR; */ unsigned char *MBRbuffer; +int MBRbuffer_changed; + /* * per partition table entry data * @@ -934,6 +936,7 @@ dos_set_mbr_id(void) { return; dos_write_mbr_id(MBRbuffer, new_id); + MBRbuffer_changed = 1; dos_print_mbr_id(); } @@ -2553,10 +2556,18 @@ write_table(void) { int i; if (dos_label) { - for (i=0; i<3; i++) - if (ptes[i].changed) - ptes[3].changed = 1; - for (i = 3; i < partitions; i++) { + /* MBR (primary partitions) */ + if (!MBRbuffer_changed) { + for (i = 0; i < 4; i++) + if (ptes[i].changed) + MBRbuffer_changed = 1; + } + if (MBRbuffer_changed) { + write_part_table_flag(MBRbuffer); + write_sector(fd, 0, MBRbuffer); + } + /* EBR (logical partitions) */ + for (i = 4; i < partitions; i++) { struct pte *pe = &ptes[i]; if (pe->changed) { diff --git a/tests/expected/fdisk/id b/tests/expected/fdisk/id new file mode 100644 index 00000000..4801f816 --- /dev/null +++ b/tests/expected/fdisk/id @@ -0,0 +1,5 @@ +Initialize empty image +Create MBR with ID=0x1 +Disk identifier: 0x00000001 +Create MBR with ID=0x2 +Disk identifier: 0x00000002 diff --git a/tests/ts/fdisk/id b/tests/ts/fdisk/id new file mode 100755 index 00000000..99840a25 --- /dev/null +++ b/tests/ts/fdisk/id @@ -0,0 +1,37 @@ +#!/bin/bash + +# +# This file is part of util-linux-ng. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +TS_TOPDIR="$(dirname $0)/../.." +TS_DESC="doslabel tests" + +. $TS_TOPDIR/functions.sh +ts_init "$*" + +FDISK_CMD_ID1="x\ni\n0x1\nr\nw\n" +FDISK_CMD_ID2="x\ni\n0x2\nr\nw\n" + +ts_log "Initialize empty image" +TEST_IMAGE_NAME=$(ts_image_init 10) + +ts_log "Create MBR with ID=0x1" +echo -e "${FDISK_CMD_ID1}" | $TS_CMD_FDISK ${TEST_IMAGE_NAME} &> /dev/null +$TS_CMD_FDISK -l ${TEST_IMAGE_NAME} | grep identifier >> $TS_OUTPUT + +ts_log "Create MBR with ID=0x2" +echo -e "${FDISK_CMD_ID2}" | $TS_CMD_FDISK ${TEST_IMAGE_NAME} &> /dev/null +$TS_CMD_FDISK -l ${TEST_IMAGE_NAME} | grep identifier >> $TS_OUTPUT + +ts_finalize -- cgit v1.2.3 From faab23b9b9c1ae51d5218debf27d1dfb9a138e87 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 9 Aug 2010 13:33:17 +0200 Subject: cfdisk: fix n+1 again Reported-by: J B Signed-off-by: Karel Zak --- fdisk/cfdisk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c index 610b8471..8801a851 100644 --- a/fdisk/cfdisk.c +++ b/fdisk/cfdisk.c @@ -1659,7 +1659,7 @@ fill_p_info(void) { bs, 1, &errmsg)) { char *bad = _("Bad logical partition"); char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30); - sprintf(msg, "%s %d: %s", bad, i + 1, errmsg); + sprintf(msg, "%s %d: %s", bad, i, errmsg); fatal(msg, 4); } } -- cgit v1.2.3 From f2813fcec4a2a8dd98f78b8ee825900c4ba2c282 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 10 Aug 2010 09:06:29 +0200 Subject: docs: add note about sfdisk to TODO Signed-off-by: Karel Zak --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 020e6ea0..62c2cbb5 100644 --- a/TODO +++ b/TODO @@ -21,6 +21,7 @@ libblkid ... blkid_unref(tp); + blkid(8) - add a new option (-r) that allows to print removable block devices that @@ -36,6 +37,9 @@ wipefs fdisk(s) -------- + * sfdisk rounds to cylinders is -uM (megabyte units) is specified, this is + pretty stupid feature. It has to round to sectors if -uS or -uM is specified. + * Sun label support is completely useless for large disks, it uses number of cylinders from on-disk-label where the geometry is stored by int16 values. It seems better to completely ignore this stuff from the label and always -- cgit v1.2.3 From aac1e59ebb205d0ae5a0480900bab22ae34729d9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 11 Aug 2010 12:43:25 +0200 Subject: lscpu: support offline CPUs # echo 0 >/sys/devices/system/cpu/cpu3/online # echo 0 >/sys/devices/system/cpu/cpu2/online # grep processor /proc/cpuinfo processor : 0 processor : 1 # lscpu lscpu: error: cannot open /sys/devices/system/cpu/cpu2/cache/index0/shared_cpu_map: No such file or directory This patch also add a new "On-line CPU(s):" line to the lscpu(1) output. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=623012 Signed-off-by: Karel Zak --- sys-utils/lscpu.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 74f5e781..eff655c4 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -101,6 +101,7 @@ struct lscpu_desc { int mode; /* rm, lm or/and tm */ int ncpus; /* number of CPUs */ + cpu_set_t *online; /* mask with online CPUs */ int nnodes; /* number of NUMA modes */ cpu_set_t **nodemaps; /* array with NUMA nodes */ @@ -125,6 +126,10 @@ static size_t sysrootlen; static char pathbuf[PATH_MAX]; static int maxcpus; /* size in bits of kernel cpu mask */ +#define is_cpu_online(_d, _cpu) \ + ((_d) && (_d)->online ? \ + CPU_ISSET_S((_cpu), CPU_ALLOC_SIZE(maxcpus), (_d)->online) : 0) + static FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...) __attribute__ ((__format__ (__printf__, 3, 4))); static void path_getstr(char *result, size_t len, const char *path, ...) @@ -235,17 +240,14 @@ xstrdup(const char *str) } static cpu_set_t * -path_cpuset(const char *path, ...) +path_cpuparse(int islist, const char *path, va_list ap) { FILE *fd; - va_list ap; cpu_set_t *set; size_t setsize, len = maxcpus * 7; char buf[len]; - va_start(ap, path); fd = path_vfopen("r", 1, path, ap); - va_end(ap); if (!fgets(buf, len, fd)) err(EXIT_FAILURE, _("failed to read: %s"), pathbuf); @@ -259,8 +261,38 @@ path_cpuset(const char *path, ...) if (!set) err(EXIT_FAILURE, _("failed to callocate cpu set")); - if (cpumask_parse(buf, set, setsize)) - errx(EXIT_FAILURE, _("failed to parse CPU mask %s"), buf); + if (islist) { + if (cpulist_parse(buf, set, setsize)) + errx(EXIT_FAILURE, _("failed to parse CPU list %s"), buf); + } else { + if (cpumask_parse(buf, set, setsize)) + errx(EXIT_FAILURE, _("failed to parse CPU mask %s"), buf); + } + return set; +} + +static cpu_set_t * +path_cpuset(const char *path, ...) +{ + va_list ap; + cpu_set_t *set; + + va_start(ap, path); + set = path_cpuparse(0, path, ap); + va_end(ap); + + return set; +} + +static cpu_set_t * +path_cpulist(const char *path, ...) +{ + va_list ap; + cpu_set_t *set; + + va_start(ap, path); + set = path_cpuparse(1, path, ap); + va_end(ap); return set; } @@ -365,6 +397,9 @@ read_basicinfo(struct lscpu_desc *desc) /* we are reading some /sys snapshot instead of the real /sys, * let's use any crazy number... */ maxcpus = desc->ncpus > 2048 ? desc->ncpus : 2048; + + /* get mask for online CPUs */ + desc->online = path_cpulist(_PATH_SYS_SYSTEM "/cpu/online"); } static int @@ -523,7 +558,8 @@ read_topology(struct lscpu_desc *desc, int num) "/cpu%d/topology/thread_siblings", num); core_siblings = path_cpuset(_PATH_SYS_CPU "/cpu%d/topology/core_siblings", num); - if (num == 0) { + + if (!desc->coremaps) { int ncores, nsockets, nthreads; size_t setsize = CPU_ALLOC_SIZE(maxcpus); @@ -563,7 +599,7 @@ read_cache(struct lscpu_desc *desc, int num) char buf[256]; int i; - if (num == 0) { + if (!desc->ncaches) { while(path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d/cache/index%d", num, desc->ncaches)) desc->ncaches++; @@ -670,6 +706,9 @@ print_parsable(struct lscpu_desc *desc) for (i = 0; i < desc->ncpus; i++) { + if (!is_cpu_online(desc, i)) + continue; + /* #CPU */ printf("%d", i); @@ -734,6 +773,7 @@ print_readable(struct lscpu_desc *desc) { char buf[512]; int i; + size_t setsize = CPU_ALLOC_SIZE(maxcpus); print_s(_("Architecture:"), desc->arch); @@ -757,6 +797,7 @@ print_readable(struct lscpu_desc *desc) } print_n(_("CPU(s):"), desc->ncpus); + print_n(_("On-line CPU(s):"), CPU_COUNT_S(setsize, desc->online)); if (desc->nsockets) { print_n(_("Thread(s) per core:"), desc->nthreads / desc->ncores); @@ -806,7 +847,7 @@ print_readable(struct lscpu_desc *desc) print_s(buf, cpulist_create( setbuf, setbuflen, desc->nodemaps[i], - CPU_ALLOC_SIZE(maxcpus))); + setsize)); } } } @@ -861,6 +902,8 @@ int main(int argc, char *argv[]) read_basicinfo(desc); for (i = 0; i < desc->ncpus; i++) { + if (!is_cpu_online(desc, i)) + continue; read_topology(desc, i); read_cache(desc, i); } -- cgit v1.2.3 From 4f912c6ac5f62b801fc9078aa0517bb72ce6bd1b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 11 Aug 2010 15:41:48 +0200 Subject: lscpu: add -x and {On,Off}-line CPU(s) mask/list Signed-off-by: Karel Zak --- sys-utils/lscpu.1 | 4 +++ sys-utils/lscpu.c | 73 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/sys-utils/lscpu.1 b/sys-utils/lscpu.1 index 4f78ee6b..30e08a57 100644 --- a/sys-utils/lscpu.1 +++ b/sys-utils/lscpu.1 @@ -22,6 +22,10 @@ Print a help message. .TP .BR \-p , " \-\-parse" Print out in parsable instead of printable format. +.TP +.BR \-x , " \-\-hex" +Use hexadecimal masks for CPU(s) sets (e.g. 0x3). The default is print the sets +in the list format (e.g. 0,1). .SH BUGS The basic overview about CPU family, model, etc. is always based on the first CPU only. diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index eff655c4..58cd869d 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -769,7 +769,24 @@ print_parsable(struct lscpu_desc *desc) #define print_n(_key, _val) printf("%-23s%d\n", _key, _val) static void -print_readable(struct lscpu_desc *desc) +print_cpuset(const char *key, cpu_set_t *set, int hex) +{ + size_t setsize = CPU_ALLOC_SIZE(maxcpus); + size_t setbuflen = 7 * maxcpus; + char setbuf[setbuflen], *p; + + if (hex) { + p = cpumask_create(setbuf, setbuflen, set, setsize); + printf("%-23s0x%s\n", key, p); + } else { + p = cpulist_create(setbuf, setbuflen, set, setsize); + print_s(key, p); + } + +} + +static void +print_readable(struct lscpu_desc *desc, int hex) { char buf[512]; int i; @@ -797,7 +814,31 @@ print_readable(struct lscpu_desc *desc) } print_n(_("CPU(s):"), desc->ncpus); - print_n(_("On-line CPU(s):"), CPU_COUNT_S(setsize, desc->online)); + + print_cpuset(hex ? _("On-line CPU(s) mask:") : + _("On-line CPU(s) list:"), + desc->online, hex); + + if (CPU_COUNT_S(setsize, desc->online) != desc->ncpus) { + cpu_set_t *set; + + /* Linux kernel provides cpuset of off-line CPUs that contains + * all configured CPUs (see /sys/devices/system/cpu/offline), + * but want to print real (present in system) off-line CPUs only. + */ + set = cpuset_alloc(maxcpus, NULL, NULL); + if (!set) + err(EXIT_FAILURE, _("failed to callocate cpu set")); + CPU_ZERO_S(setsize, set); + for (i = 0; i < desc->ncpus; i++) { + if (!is_cpu_online(desc, i)) + CPU_SET_S(i, setsize, set); + } + print_cpuset(hex ? _("Off-line CPU(s) mask:") : + _("Off-line CPU(s) list:"), + set, hex); + cpuset_free(set); + } if (desc->nsockets) { print_n(_("Thread(s) per core:"), desc->nthreads / desc->ncores); @@ -838,17 +879,9 @@ print_readable(struct lscpu_desc *desc) } } - if (desc->nnodes) { - size_t setbuflen = 7 * maxcpus; - char setbuf[setbuflen]; - - for (i = 0; i < desc->nnodes; i++) { - snprintf(buf, sizeof(buf), _("NUMA node%d CPU(s):"), i); - print_s(buf, cpulist_create( - setbuf, setbuflen, - desc->nodemaps[i], - setsize)); - } + for (i = 0; i < desc->nnodes; i++) { + snprintf(buf, sizeof(buf), _("NUMA node%d CPU(s):"), i); + print_cpuset(buf, desc->nodemaps[i], hex); } } @@ -860,19 +893,22 @@ void usage(int rc) puts(_( "CPU architecture information helper\n\n" " -h, --help usage information\n" " -p, --parse print out in parsable instead of printable format.\n" - " -s, --sysroot use the directory as a new system root.\n")); + " -s, --sysroot use the directory as a new system root.\n" + " -x, --hex print haxadecimal masks rather than lists of CPU(s)\n")); + exit(rc); } int main(int argc, char *argv[]) { struct lscpu_desc _desc, *desc = &_desc; - int parsable = 0, c, i; + int parsable = 0, c, i, hex = 0; struct option longopts[] = { { "help", no_argument, 0, 'h' }, { "parse", no_argument, 0, 'p' }, { "sysroot", required_argument, 0, 's' }, + { "hex", no_argument, 0, 'x' }, { NULL, 0, 0, 0 } }; @@ -880,7 +916,7 @@ int main(int argc, char *argv[]) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - while((c = getopt_long(argc, argv, "hps:", longopts, NULL)) != -1) { + while((c = getopt_long(argc, argv, "hps:x", longopts, NULL)) != -1) { switch (c) { case 'h': usage(EXIT_SUCCESS); @@ -892,6 +928,9 @@ int main(int argc, char *argv[]) strncpy(pathbuf, optarg, sizeof(pathbuf)); pathbuf[sizeof(pathbuf) - 1] = '\0'; break; + case 'x': + hex = 1; + break; default: usage(EXIT_FAILURE); } @@ -918,7 +957,7 @@ int main(int argc, char *argv[]) if (parsable) print_parsable(desc); else - print_readable(desc); + print_readable(desc, hex); return EXIT_SUCCESS; } -- cgit v1.2.3 From a09f0933bb80c52ec1bc30a1678cef7e999aeff9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 13 Aug 2010 09:59:31 +0200 Subject: libblkid: wrong PT detection on RAID0 Reported-by: Yulia Kopkova Signed-off-by: Karel Zak --- shlibs/blkid/src/partitions/partitions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c index 5597181a..d6abc203 100644 --- a/shlibs/blkid/src/partitions/partitions.c +++ b/shlibs/blkid/src/partitions/partitions.c @@ -833,7 +833,7 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr, for (i = 0; i < nparts; i++) { blkid_partition par = &ls->parts[i]; - if (par->start + par->size > pr->size) { + if (par->start + par->size > (pr->size >> 9)) { DBG(DEBUG_LOWPROBE, printf("partition #%d overflows " "device (off=%lu size=%lu)\n", par->partno, par->start, par->size)); -- cgit v1.2.3 From 848e5e6ce3978d921366b799d907a78a12299924 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 18 Aug 2010 09:02:03 +0200 Subject: agetty: add -s to reuse existing baud rate For example: /sbin/agetty -s /dev/ttyS0 9600 will reuse the speed the kernel configured on the port. If the setting from kernel is useless (tty returns BREAK character) then the baud rate from command line (9600) is used. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=623685 Signed-off-by: Karel Zak --- login-utils/agetty.8 | 16 +++++----------- login-utils/agetty.c | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/login-utils/agetty.8 b/login-utils/agetty.8 index 87613747..53037dda 100644 --- a/login-utils/agetty.8 +++ b/login-utils/agetty.8 @@ -3,7 +3,7 @@ agetty \- alternative Linux getty .SH SYNOPSIS -.BR "agetty " [\-8ihLmnUw] +.BR "agetty " [\-8ihLmnsUw] .RI "[-f " issue_file ] .RI "[-l " login_program ] .RI "[-I " init ] @@ -12,16 +12,6 @@ agetty \- alternative Linux getty .I port .I baud_rate,... .RI [ term ] -.br -.BR "agetty " [\-8ihLmnw] -.RI "[-f " issue_file ] -.RI "[-l " login_program ] -.RI "[-I " init ] -.RI "[-t " timeout ] -.RI "[-H " login_host ] -.I baud_rate,... -.I port -.RI [ term ] .SH DESCRIPTION .ad @@ -163,6 +153,10 @@ Force the line to be a local line with no need for carrier detect. This can be useful when you have a locally attached terminal where the serial line does not set the carrier detect signal. .TP +\-s +Try to keep the existing baud rate. The baud rates from +the command line are used when agetty receives a BREAK character. +.TP \-U Turn on support for detecting an uppercase only terminal. This setting will detect a login name containing only capitals as indicating an uppercase diff --git a/login-utils/agetty.c b/login-utils/agetty.c index 39a1fd3e..9fc389b8 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -133,6 +133,7 @@ struct options { #define F_CUSTISSUE (1<<6) /* give alternative issue file */ #define F_NOPROMPT (1<<7) /* don't ask for login name! */ #define F_LCUC (1<<8) /* Support for *LCUC stty modes */ +#define F_KEEPSPEED (1<<9) /* Follow baud rate from kernel */ /* Storage for things detected while the login name was read. */ @@ -203,7 +204,7 @@ void parse_args P_((int argc, char **argv, struct options *op)); void parse_speeds P_((struct options *op, char *arg)); void update_utmp P_((char *line)); void open_tty P_((char *tty, struct termios *tp, int local)); -void termio_init P_((struct termios *tp, int speed, struct options *op)); +void termio_init P_((struct termios *tp, struct options *op)); void auto_baud P_((struct termios *tp)); void do_prompt P_((struct options *op, struct termios *tp)); void next_speed P_((struct termios *tp, struct options *op)); @@ -297,7 +298,7 @@ main(argc, argv) tcsetpgrp(0, getpid()); /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ debug("calling termio_init\n"); - termio_init(&termios, options.speeds[FIRST_SPEED], &options); + termio_init(&termios, &options); /* write the modem init string and DON'T flush the buffers */ if (options.flags & F_INITSTRING) { @@ -373,7 +374,7 @@ parse_args(argc, argv, op) extern int optind; /* getopt */ int c; - while (isascii(c = getopt(argc, argv, "8I:LH:f:hil:mt:wUn"))) { + while (isascii(c = getopt(argc, argv, "8I:LH:f:hil:mst:wUn"))) { switch (c) { case '8': op->eightbits = 1; @@ -443,6 +444,9 @@ parse_args(argc, argv, op) case 'n': op->flags |= F_NOPROMPT; break; + case 's': + op->flags |= F_KEEPSPEED; /* keep kernel defined speed */ + break; case 't': /* time out */ if ((op->timeout = atoi(optarg)) <= 0) error(_("bad timeout value: %s"), optarg); @@ -691,9 +695,8 @@ char gbuf[1024]; char area[1024]; void -termio_init(tp, speed, op) +termio_init(tp, op) struct termios *tp; - int speed; struct options *op; { @@ -707,8 +710,11 @@ termio_init(tp, speed, op) (void) tcflush(0, TCIOFLUSH); tp->c_cflag = CS8 | HUPCL | CREAD; - cfsetispeed(tp, speed); - cfsetospeed(tp, speed); + + if (!(op->flags & F_KEEPSPEED)) { + cfsetispeed(tp, op->speeds[FIRST_SPEED]); + cfsetospeed(tp, op->speeds[FIRST_SPEED]); + } if (op->flags & F_LOCAL) { tp->c_cflag |= CLOCAL; } @@ -1203,7 +1209,7 @@ bcode(s) void usage() { - fprintf(stderr, _("Usage: %s [-8hiLmUw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname); + fprintf(stderr, _("Usage: %s [-8hiLmsUw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname); exit(1); } -- cgit v1.2.3 From e143d1f00497f0178a1febec8fb4aa7c842fa35a Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 12 Jul 2010 11:57:55 +0200 Subject: aggety: don't wipe CLOCAL flag gettey should not clear the flag. It seems that the flag is automatically enabled for serial consoles tht don't use CD signal. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=598631 Signed-off-by: Karel Zak --- login-utils/agetty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/login-utils/agetty.c b/login-utils/agetty.c index 9fc389b8..25419481 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -709,7 +709,7 @@ termio_init(tp, op) /* flush input and output queues, important for modems! */ (void) tcflush(0, TCIOFLUSH); - tp->c_cflag = CS8 | HUPCL | CREAD; + tp->c_cflag = CS8 | HUPCL | CREAD | (tp->c_cflag & CLOCAL); if (!(op->flags & F_KEEPSPEED)) { cfsetispeed(tp, op->speeds[FIRST_SPEED]); -- cgit v1.2.3 From bb1eea0ee0971cf5136e346bd3a16a2fa01555da Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 18 Aug 2010 09:29:59 +0200 Subject: agetty: add -c to reuse cflags The agetty command resets terminal cflags setting. The -c option disables this behavior and serial setting from kernel is used. Signed-off-by: Karel Zak --- login-utils/agetty.8 | 6 +++++- login-utils/agetty.c | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/login-utils/agetty.8 b/login-utils/agetty.8 index 53037dda..084086fd 100644 --- a/login-utils/agetty.8 +++ b/login-utils/agetty.8 @@ -3,7 +3,7 @@ agetty \- alternative Linux getty .SH SYNOPSIS -.BR "agetty " [\-8ihLmnsUw] +.BR "agetty " [\-c8ihLmnsUw] .RI "[-f " issue_file ] .RI "[-l " login_program ] .RI "[-I " init ] @@ -82,6 +82,10 @@ whatever init(8) may have set, and is inherited by login and the shell. .fi .ad .TP +\-c +Don't reset terminal cflags (control modes). See \fItermios(3)\fP for more +details. +.TP \-8 Assume that the tty is 8-bit clean, hence disable parity detection. .TP diff --git a/login-utils/agetty.c b/login-utils/agetty.c index 25419481..a6e24998 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -134,6 +134,7 @@ struct options { #define F_NOPROMPT (1<<7) /* don't ask for login name! */ #define F_LCUC (1<<8) /* Support for *LCUC stty modes */ #define F_KEEPSPEED (1<<9) /* Follow baud rate from kernel */ +#define F_KEEPCFLAGS (1<<10) /* Reuse c_cflags setup from kernel */ /* Storage for things detected while the login name was read. */ @@ -374,8 +375,11 @@ parse_args(argc, argv, op) extern int optind; /* getopt */ int c; - while (isascii(c = getopt(argc, argv, "8I:LH:f:hil:mst:wUn"))) { + while (isascii(c = getopt(argc, argv, "8cI:LH:f:hil:mst:wUn"))) { switch (c) { + case 'c': + op->flags |= F_KEEPCFLAGS; + break; case '8': op->eightbits = 1; break; @@ -709,7 +713,8 @@ termio_init(tp, op) /* flush input and output queues, important for modems! */ (void) tcflush(0, TCIOFLUSH); - tp->c_cflag = CS8 | HUPCL | CREAD | (tp->c_cflag & CLOCAL); + if (!(op->flags & F_KEEPCFLAGS)) + tp->c_cflag = CS8 | HUPCL | CREAD | (tp->c_cflag & CLOCAL); if (!(op->flags & F_KEEPSPEED)) { cfsetispeed(tp, op->speeds[FIRST_SPEED]); -- cgit v1.2.3 From 7df072799d25cb6c744909225cd89329e1c4668b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 18 Aug 2010 09:33:11 +0200 Subject: tests: add blkid test for partitioned RAID0 Signed-off-by: Karel Zak --- tests/expected/blkid/md-raid0-whole | 51 ++++++++++++++++++++++ tests/ts/blkid/md-raid0-whole | 86 +++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 tests/expected/blkid/md-raid0-whole create mode 100755 tests/ts/blkid/md-raid0-whole diff --git a/tests/expected/blkid/md-raid0-whole b/tests/expected/blkid/md-raid0-whole new file mode 100644 index 00000000..a13647de --- /dev/null +++ b/tests/expected/blkid/md-raid0-whole @@ -0,0 +1,51 @@ +Initialize devices +Create RAID device +Create partitions on RAID device +Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel + +Changes will remain in memory only, until you decide to write them. +After that, of course, the previous content won't be recoverable. + +Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) + +Command (m for help): Command action + e extended + p primary partition (1-4) +Partition number (1-4, default 1): First sector (2048-204543, default 2048): Using default value 2048 +Last sector, +sectors or +size{K,M,G} (2048-204543, default 204543): +Command (m for help): Command action + e extended + p primary partition (1-4) +Partition number (1-4, default 2): First sector (22528-204543, default 22528): Using default value 22528 +Last sector, +sectors or +size{K,M,G} (22528-204543, default 204543): Using default value 204543 + +Command (m for help): +Disk /dev/md8: 104 MB, 104726528 bytes +2 heads, 4 sectors/track, 25568 cylinders, total 204544 sectors +Units = sectors of 1 * 512 = 512 bytes +Sector size (logical/physical): 512 bytes / 512 bytes +I/O size (minimum/optimal): 65536 bytes / 131072 bytes + + + Device Boot Start End Blocks Id System +/dev/md8p1 2048 22527 10240 83 Linux +/dev/md8p2 22528 204543 91008 83 Linux + +Command (m for help): The partition table has been altered! + +Calling ioctl() to re-read partition table. +Syncing disks. +Probe first RAID member +ID_FS_TYPE=linux_raid_member +ID_FS_USAGE=raid + + +ID_FS_VERSION=0.90.0 +Probe second RAID member +ID_FS_TYPE=linux_raid_member +ID_FS_USAGE=raid + + +ID_FS_VERSION=0.90.0 +Stop RAID device +Deinitialize devices diff --git a/tests/ts/blkid/md-raid0-whole b/tests/ts/blkid/md-raid0-whole new file mode 100755 index 00000000..3acc4a9c --- /dev/null +++ b/tests/ts/blkid/md-raid0-whole @@ -0,0 +1,86 @@ +#!/bin/bash + +# +# Copyright (C) 2010 Karel Zak +# +# This file is part of util-linux-ng. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +TS_TOPDIR="$(dirname $0)/../.." +TS_DESC="MD raid0 (whole-disks)" + +. $TS_TOPDIR/functions.sh +ts_init "$*" +ts_skip_nonroot +[ -x /sbin/mdadm ] || ts_skip "missing mdadm" + +set -o pipefail + +ts_log "Initialize devices" +IMGNAME="${TS_OUTDIR}/${TS_TESTNAME}" + +DEVICE1=$(ts_device_init 50 ${IMGNAME}1.img) +[ "$?" == 0 ] || ts_die "Cannot init device1" + +DEVICE2=$(ts_device_init 50 ${IMGNAME}2.img) +[ "$?" == 0 ] || ts_die "Cannot init device2" $DEVICE1 + +MD_DEVNAME=md8 +MD_DEVICE=/dev/${MD_DEVNAME} + +/sbin/mdadm -q -S ${MD_DEVICE} &> /dev/null + +ts_log "Create RAID device" +/sbin/mdadm -q --create ${MD_DEVICE} --metadata=0.90 --chunk=64 --level=0 \ + --raid-devices=2 ${DEVICE1} ${DEVICE2} >> $TS_OUTPUT 2>&1 + +ts_log "Create partitions on RAID device" +$TS_CMD_FDISK ${MD_DEVICE} >> $TS_OUTPUT 2>&1 <&1 | sort >> $TS_OUTPUT + +ts_log "Probe second RAID member" +$TS_CMD_BLKID -p -o udev $DEVICE1 2>&1 | sort >> $TS_OUTPUT + +ts_log "Stop RAID device" +/sbin/mdadm -q -S ${MD_DEVICE} >> $TS_OUTPUT 2>&1 + +sleep 3 + +ts_log "Deinitialize devices" +ts_device_deinit $DEVICE1 +ts_device_deinit $DEVICE2 + +# remove disk ID and generated UUIDs +sed -i -e 's/Disk identifier:.*//g' $TS_OUTPUT +sed -i -e 's/Building a new.*//g' $TS_OUTPUT +sed -i -e 's/ID_FS_UUID.*//g' $TS_OUTPUT + +ts_finalize -- cgit v1.2.3 From 0c0f93fcc37d02d9ab6d159f964da378d424199e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 19 Aug 2010 15:33:45 +0200 Subject: fsck: improve whole-disk check, detect stacked devices The current heuristic for conversion from partition to whole-disk is based on device names. It's pretty poor. This patch replaces this code with blkid_devno_to_wholedisk(). This solution is based on /sys FS and it works for arbitrary partitioned devices. The another problem is the way how fsck determines stacked devices. The current code checks device name for "md" prefix only. It does not care about DM, dm-ccypt, and so on. This patch uses /sys/block/.../slaves/, but it does not fully resolves dependencies between all devices. The method is simple -- fsck does not check stacked devices in parallel with any other device. Signed-off-by: Karel Zak --- Makefile.am | 2 + fsck/Makefile.am | 2 +- fsck/base_device.c | 169 ----------------------------------------------------- fsck/fsck.8 | 13 +++-- fsck/fsck.c | 89 +++++++++++++++++++--------- fsck/fsck.h | 5 +- 6 files changed, 77 insertions(+), 203 deletions(-) delete mode 100644 fsck/base_device.c diff --git a/Makefile.am b/Makefile.am index c489665f..9febbfd9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,8 +44,10 @@ SUBDIRS += mount endif if BUILD_FSCK +if BUILD_LIBBLKID SUBDIRS += fsck endif +endif ACLOCAL_AMFLAGS = -I m4 diff --git a/fsck/Makefile.am b/fsck/Makefile.am index b0949e25..22566d19 100644 --- a/fsck/Makefile.am +++ b/fsck/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am sbin_PROGRAMS = fsck dist_man_MANS = fsck.8 -fsck_SOURCES = base_device.c fsck.c fsck.h $(top_srcdir)/lib/ismounted.c \ +fsck_SOURCES = fsck.c fsck.h $(top_srcdir)/lib/ismounted.c \ $(top_srcdir)/lib/fsprobe.c $(top_srcdir)/lib/canonicalize.c fsck_LDADD = fsck_CFLAGS = $(AM_CFLAGS) diff --git a/fsck/base_device.c b/fsck/base_device.c deleted file mode 100644 index aad2ba05..00000000 --- a/fsck/base_device.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * base_device.c - * - * Return the "base device" given a particular device; this is used to - * assure that we only fsck one partition on a particular drive at any - * one time. Otherwise, the disk heads will be seeking all over the - * place. If the base device can not be determined, return NULL. - * - * The base_device() function returns an allocated string which must - * be freed. - * - * Written by Theodore Ts'o, - * - * Copyright (C) 2000 Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU Public - * License. - * %End-Header% - */ -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_STDLIB_H -#include -#endif -#include -#include - -#include "fsck.h" - -/* - * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3 - * pathames. - */ -static const char *devfs_hier[] = { - "host", "bus", "target", "lun", 0 -}; - -char *base_device(const char *device) -{ - char *str, *cp; - const char **hier, *disk; - int len; - - str = malloc(strlen(device)+1); - if (!str) - return NULL; - strcpy(str, device); - cp = str; - - /* Skip over /dev/; if it's not present, give up. */ - if (strncmp(cp, "/dev/", 5) != 0) - goto errout; - cp += 5; - - /* Skip over /dev/dsk/... */ - if (strncmp(cp, "dsk/", 4) == 0) - cp += 4; - - /* - * For md devices, we treat them all as if they were all - * on one disk, since we don't know how to parallelize them. - */ - if (cp[0] == 'm' && cp[1] == 'd') { - *(cp+2) = 0; - return str; - } - - /* Handle DAC 960 devices */ - if (strncmp(cp, "rd/", 3) == 0) { - cp += 3; - if (cp[0] != 'c' || cp[2] != 'd' || - !isdigit(cp[1]) || !isdigit(cp[3])) - goto errout; - *(cp+4) = 0; - return str; - } - - /* Now let's handle /dev/hd* and /dev/sd* devices.... */ - if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) { - cp += 2; - /* If there's a single number after /dev/hd, skip it */ - if (isdigit(*cp)) - cp++; - /* What follows must be an alpha char, or give up */ - if (!isalpha(*cp)) - goto errout; - *(cp + 1) = 0; - return str; - } - - /* Now let's handle devfs (ugh) names */ - len = 0; - if (strncmp(cp, "ide/", 4) == 0) - len = 4; - if (strncmp(cp, "scsi/", 5) == 0) - len = 5; - if (len) { - cp += len; - /* - * Now we proceed down the expected devfs hierarchy. - * i.e., .../host1/bus2/target3/lun4/... - * If we don't find the expected token, followed by - * some number of digits at each level, abort. - */ - for (hier = devfs_hier; *hier; hier++) { - len = strlen(*hier); - if (strncmp(cp, *hier, len) != 0) - goto errout; - cp += len; - while (*cp != '/' && *cp != 0) { - if (!isdigit(*cp)) - goto errout; - cp++; - } - cp++; - } - *(cp - 1) = 0; - return str; - } - - /* Now handle devfs /dev/disc or /dev/disk names */ - disk = 0; - if (strncmp(cp, "discs/", 6) == 0) - disk = "disc"; - else if (strncmp(cp, "disks/", 6) == 0) - disk = "disk"; - if (disk) { - cp += 6; - if (strncmp(cp, disk, 4) != 0) - goto errout; - cp += 4; - while (*cp != '/' && *cp != 0) { - if (!isdigit(*cp)) - goto errout; - cp++; - } - *cp = 0; - return str; - } - -errout: - free(str); - return NULL; -} - -#ifdef DEBUG -int main(int argc, char** argv) -{ - const char *base; - char buf[256], *cp; - - while (1) { - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - cp = strchr(buf, '\n'); - if (cp) - *cp = 0; - cp = strchr(buf, '\t'); - if (cp) - *cp = 0; - base = base_device(buf); - printf("%s\t%s\n", buf, base ? base : "NONE"); - } - exit(0); -} -#endif diff --git a/fsck/fsck.8 b/fsck/fsck.8 index 027fb3fe..9cf80785 100644 --- a/fsck/fsck.8 +++ b/fsck/fsck.8 @@ -200,6 +200,11 @@ If there are multiple filesystems with the same pass number, fsck will attempt to check them in parallel, although it will avoid running multiple filesystem checks on the same physical disk. .sp +.B fsck +does not check stacked devices (RAIDs, dm-crypt, ...) in parallel with any other +device. See below for FSCK_FORCE_ALL_PARALLEL setting. The /sys filesystem is +used to detemine dependencies between devices. +.sp Hence, a very common configuration in .I /etc/fstab files is to set the root filesystem to have a @@ -366,10 +371,10 @@ program's behavior is affected by the following environment variables: .B FSCK_FORCE_ALL_PARALLEL If this environment variable is set, .B fsck -will attempt to run all of the specified filesystems in parallel, -regardless of whether the filesystems appear to be on the same -device. (This is useful for RAID systems or high-end storage systems -such as those sold by companies such as IBM or EMC.) +will attempt to run all of the specified filesystems in parallel, regardless of +whether the filesystems appear to be on the same device. (This is useful for +RAID systems or high-end storage systems such as those sold by companies such +as IBM or EMC.) Note that the fs_passno value is still used. .TP .B FSCK_MAX_INST This environment variable will limit the maximum number of file system diff --git a/fsck/fsck.c b/fsck/fsck.c index 7577eff1..e7526f9e 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include "fsprobe.h" @@ -217,8 +219,6 @@ static void parse_escape(char *word) static void free_instance(struct fsck_instance *i) { free(i->prog); - free(i->device); - free(i->base_device); free(i); return; } @@ -240,6 +240,8 @@ static struct fs_info *create_fs_device(const char *device, const char *mntpnt, fs->passno = passno; fs->flags = 0; fs->next = NULL; + fs->disk = 0; + fs->stacked = 0; if (!filesys_info) filesys_info = fs; @@ -414,8 +416,7 @@ static int progress_active(NOARGS) * Execute a particular fsck program, and link it into the list of * child processes we are waiting for. */ -static int execute(const char *type, const char *device, const char *mntpt, - int interactive) +static int execute(const char *type, struct fs_info *fs, int interactive) { char *s, *argv[80], prog[80]; int argc, i; @@ -452,7 +453,7 @@ static int execute(const char *type, const char *device, const char *mntpt, } } - argv[argc++] = string_copy(device); + argv[argc++] = string_copy(fs->device); argv[argc] = 0; s = find_fsck(prog); @@ -464,7 +465,7 @@ static int execute(const char *type, const char *device, const char *mntpt, if (verbose || noexecute) { printf("[%s (%d) -- %s] ", s, num_running, - mntpt ? mntpt : device); + fs->mountpt ? fs->mountpt : fs->device); for (i=0; i < argc; i++) printf("%s ", argv[i]); printf("\n"); @@ -492,9 +493,8 @@ static int execute(const char *type, const char *device, const char *mntpt, inst->pid = pid; inst->prog = string_copy(prog); inst->type = string_copy(type); - inst->device = string_copy(device); - inst->base_device = base_device(device); inst->start_time = time(0); + inst->fs = fs; inst->next = NULL; /* @@ -597,12 +597,12 @@ static struct fsck_instance *wait_one(int flags) } else { printf(_("Warning... %s for device %s exited " "with signal %d.\n"), - inst->prog, inst->device, sig); + inst->prog, inst->fs->device, sig); status = EXIT_ERROR; } } else { printf(_("%s %s: status is %x, should never happen.\n"), - inst->prog, inst->device, status); + inst->prog, inst->fs->device, status); status = EXIT_ERROR; } inst->exit_status = status; @@ -641,7 +641,7 @@ ret_inst: instance_list = inst->next; if (verbose > 1) printf(_("Finished with %s (exit status %d)\n"), - inst->device, inst->exit_status); + inst->fs->device, inst->exit_status); num_running--; return inst; } @@ -698,7 +698,7 @@ static void fsck_device(struct fs_info *fs, int interactive) type = DEFAULT_FSTYPE; num_running++; - retval = execute(type, fs->device, fs->mountpt, interactive); + retval = execute(type, fs, interactive); if (retval) { fprintf(stderr, _("%s: Error %d while executing fsck.%s " "for %s\n"), progname, retval, type, fs->device); @@ -924,40 +924,75 @@ static int ignore(struct fs_info *fs) return 0; } +static int count_slaves(dev_t disk) +{ + DIR *dir; + struct dirent *dp; + char dirname[PATH_MAX]; + int count = 0; + + snprintf(dirname, sizeof(dirname), + "/sys/dev/block/%u:%u/slaves/", + major(disk), minor(disk)); + + if (!(dir = opendir(dirname))) + return -1; + + while ((dp = readdir(dir)) != 0) { +#ifdef _DIRENT_HAVE_D_TYPE + if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK) + continue; +#endif + if (dp->d_name[0] == '.' && + ((dp->d_name[1] == 0) || + ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) + continue; + + count++; + } + closedir(dir); + return count; +} + /* * Returns TRUE if a partition on the same disk is already being * checked. */ -static int device_already_active(char *device) +static int disk_already_active(struct fs_info *fs) { struct fsck_instance *inst; - char *base; if (force_all_parallel) return 0; -#ifdef BASE_MD - /* Don't check a soft raid disk with any other disk */ - if (instance_list && - (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) || - !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))) + if (instance_list && instance_list->fs->stacked) + /* any instance for a stacked device is already running */ return 1; -#endif - base = base_device(device); + if (!fs->disk) { + struct stat st; + dev_t disk; + + if (!stat(fs->device, &st) && + !blkid_devno_to_wholedisk(st.st_rdev, NULL, 0, &disk)) { + fs->disk = disk; + fs->stacked = count_slaves(disk); + } + } + /* * If we don't know the base device, assume that the device is * already active if there are any fsck instances running. + * + * Don't check a stacked device with any other disk too. */ - if (!base) + if (!fs->disk || fs->stacked) return (instance_list != 0); + for (inst = instance_list; inst; inst = inst->next) { - if (!inst->base_device || !strcmp(base, inst->base_device)) { - free(base); + if (!inst->fs->disk || fs->disk == inst->fs->disk) return 1; - } } - free(base); return 0; } @@ -1038,7 +1073,7 @@ static int check_all(NOARGS) * already been spawned, then we need to defer * this to another pass. */ - if (device_already_active(fs->device)) { + if (disk_already_active(fs)) { pass_done = 0; continue; } diff --git a/fsck/fsck.h b/fsck/fsck.h index 45b78446..d212622f 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -44,6 +44,8 @@ struct fs_info { int freq; int passno; int flags; + dev_t disk; + int stacked; struct fs_info *next; }; @@ -60,8 +62,7 @@ struct fsck_instance { time_t start_time; char * prog; char * type; - char * device; - char * base_device; + struct fs_info *fs; struct fsck_instance *next; }; -- cgit v1.2.3 From 1fc0b941d6d14ac2b8a5b0e40ab3c9981c034d41 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 20 Aug 2010 11:45:00 +0200 Subject: flock: properly report exec() errors Reported-by: Barry Davis Signed-off-by: Karel Zak --- sys-utils/flock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys-utils/flock.c b/sys-utils/flock.c index 1f1c563b..20004cae 100644 --- a/sys-utils/flock.c +++ b/sys-utils/flock.c @@ -298,8 +298,8 @@ int main(int argc, char *argv[]) } else if ( f == 0 ) { if ( do_close ) close(fd); - err = errno; execvp(cmd_argv[0], cmd_argv); + err = errno; /* execvp() failed */ fprintf(stderr, "%s: %s: %s\n", program, cmd_argv[0], strerror(err)); _exit((err == ENOMEM) ? EX_OSERR: EX_UNAVAILABLE); -- cgit v1.2.3 From 06eee0d84f41dffe5ad0a894a9ec3123f43caf13 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2010 17:03:56 -0400 Subject: rev: coding style, various fixes * Change indentation to 8 characters and coding style, for better reading the code. * Add some memory allocation error handling. * Fix memory leaks. In cases when Ctrl-C is used to exit the program, 'p' cannot be freed, so made it a global var, to share between main() and sig_handler(). Signal handing is necessary to fix some leaks, so added a very basic, non invasive, mechanism. Signed-off-by: Davidlohr Bueso Signed-off-by: Karel Zak --- text-utils/rev.c | 195 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 110 insertions(+), 85 deletions(-) diff --git a/text-utils/rev.c b/text-utils/rev.c index 3ae38cfd..907b032b 100644 --- a/text-utils/rev.c +++ b/text-utils/rev.c @@ -36,12 +36,16 @@ * Wed Sep 14 22:26:00 1994: Patch from bjdouma to handle * last line that has no newline correctly. * 3-Jun-1998: Patched by Nicolai Langfeldt to work better on Linux: - * Handle any-length-lines. Code copied from util-linux' setpwnam.c + * Handle any-length-lines. Code copied from util-linux' setpwnam.c * 1999-02-22 Arkadiusz Mi¶kiewicz - * added Native Language Support + * added Native Language Support * 1999-09-19 Bruno Haible - * modified to work correctly in multi-byte locales - * + * modified to work correctly in multi-byte locales + * July 2010 - Davidlohr Bueso + * Fixed memory leaks (including Linux signal handling) + * Added some memory allocation error handling + * Lowered the default buffer size to 256, instead of 512 bytes + * Changed tab indentation to 8 chars for better reading the code */ #include @@ -52,94 +56,115 @@ #include #include #include +#include #include "nls.h" #include "widechar.h" -void usage(void); +wchar_t *buf; -int -main(int argc, char *argv[]) +static void sig_handler(int signo) { - register char *filename; - register wchar_t *t; - size_t buflen = 512; - wchar_t *p = malloc(buflen*sizeof(wchar_t)); - size_t len; - FILE *fp; - int ch, rval; - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - - while ((ch = getopt(argc, argv, "")) != -1) - switch(ch) { - case '?': - default: - usage(); - } - - argc -= optind; - argv += optind; - - fp = stdin; - filename = "stdin"; - rval = 0; - do { - if (*argv) { - if ((fp = fopen(*argv, "r")) == NULL) { - warn("cannot open %s", *argv ); - rval = 1; - ++argv; - continue; - } - filename = *argv++; - } - - while (fgetws(p, buflen, fp)) { - - len = wcslen(p); - - /* This is my hack from setpwnam.c -janl */ - while (p[len-1] != '\n' && !feof(fp)) { - /* Extend input buffer if it failed getting the whole line */ - - /* So now we double the buffer size */ - buflen *= 2; - - p = realloc(p, buflen*sizeof(wchar_t)); - if (p == NULL) - err(1, _("unable to allocate bufferspace")); - - /* And fill the rest of the buffer */ - if (fgetws(&p[len], buflen/2, fp) == NULL) break; - - len = wcslen(p); - - /* That was a lot of work for nothing. Gimme perl! */ - } - - t = p + len - 1 - (*(p+len-1)=='\r' || *(p+len-1)=='\n'); - for ( ; t >= p; --t) - if (*t != 0) - putwchar(*t); - putwchar('\n'); - } - fflush(fp); - if (ferror(fp)) { - warn("%s", filename); - rval = 1; - } - if (fclose(fp)) - rval = 1; - } while(*argv); - exit(rval); + free(buf); + exit(EXIT_SUCCESS); } -void -usage(void) +static void __attribute__((__noreturn__)) usage(FILE *out) { - (void)fprintf(stderr, _("usage: rev [file ...]\n")); - exit(1); + fprintf(out, _("Usage: %s [file ...]\n"), + program_invocation_short_name); + + fprintf(out, _("\nFor more information see rev(1).\n")); + + exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } + +int main(int argc, char *argv[]) +{ + char *filename = "stdin"; + wchar_t *t; + size_t len, bufsiz = BUFSIZ; + FILE *fp = stdin; + int ch, rval = EXIT_SUCCESS; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + + while ((ch = getopt(argc, argv, "")) != -1) + switch(ch) { + case '?': + case 'h': + usage(stdout); + default: + usage(stderr); + } + + argc -= optind; + argv += optind; + + do { + if (*argv) { + if ((fp = fopen(*argv, "r")) == NULL) { + warn(_("%s: open failed"), *argv ); + rval = EXIT_FAILURE; + ++argv; + continue; + } + filename = *argv++; + } + + buf = malloc(bufsiz * sizeof(wchar_t)); + if (!buf) + err(EXIT_FAILURE, _("malloc failed")); + + while (fgetws(buf, bufsiz, fp)) { + len = wcslen(buf); + + /* This is my hack from setpwnam.c -janl */ + while (buf[len-1] != '\n' && !feof(fp)) { + wchar_t *x; + + /* Extend input buffer if it failed getting the whole line */ + + /* So now we double the buffer size */ + bufsiz *= 2; + + x = realloc(buf, bufsiz * sizeof(wchar_t)); + if (!x) { + free(buf); + err(EXIT_FAILURE, _("realloc failed")); + } + buf = x; + + /* And fill the rest of the buffer */ + if (!fgetws(&buf[len], bufsiz/2, fp)) + break; + + len = wcslen(buf); + } + + t = buf + len - 1 - (*(buf+len-1)=='\r' || *(buf+len-1)=='\n'); + for ( ; t >= buf; --t) { + if (*t != 0) + putwchar(*t); + } + putwchar('\n'); + } + + fflush(fp); + if (ferror(fp)) { + warn("%s", filename); + rval = EXIT_FAILURE; + } + if (fclose(fp)) + rval = EXIT_FAILURE; + } while(*argv); + + free(buf); + return rval; +} + -- cgit v1.2.3 From ec25979447b09387c8152d570581d963df91261e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 20 Aug 2010 13:03:51 +0200 Subject: libmount: remove unused mnt_strconcat3() Signed-off-by: Karel Zak --- shlibs/mount/src/mountP.h | 2 -- shlibs/mount/src/utils.c | 27 --------------------------- 2 files changed, 29 deletions(-) diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h index ddd86ea2..6145b730 100644 --- a/shlibs/mount/src/mountP.h +++ b/shlibs/mount/src/mountP.h @@ -70,8 +70,6 @@ extern char *strndup(const char *s, size_t n); extern char *strnchr(const char *s, size_t maxlen, int c); #endif extern char *mnt_get_username(const uid_t uid); -extern char *mnt_strconcat3(char *s, const char *t, const char *u); - /* * Generic iterator diff --git a/shlibs/mount/src/utils.c b/shlibs/mount/src/utils.c index f487383a..6133cdd7 100644 --- a/shlibs/mount/src/utils.c +++ b/shlibs/mount/src/utils.c @@ -264,33 +264,6 @@ int mnt_match_options(const char *optstr, const char *pattern) return 1; } -/* - * Reallocates its first arg @s - typical use: s = mnt_strconcat3(s,t,u); - * Returns reallocated @s ion succes or NULL in case of error. - */ -char *mnt_strconcat3(char *s, const char *t, const char *u) -{ - size_t len = 0; - - len = (s ? strlen(s) : 0) + (t ? strlen(t) : 0) + (u ? strlen(u) : 0); - - if (!len) - return NULL; - if (!s) { - s = malloc(len + 1); - *s = '\0'; - } else - s = realloc(s, len + 1); - - if (!s) - return NULL; - if (t) - strcat(s, t); - if (u) - strcat(s, u); - return s; -} - /* * Returns allocated string with username or NULL. */ -- cgit v1.2.3 From 9695a7c653c5e1871f7bb78fa0e6ec8d4e74a83a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 11 Aug 2010 23:12:07 +0200 Subject: losetup: do not distinguish between malloc and realloc realloc(NULL, size) behaves the same as malloc(size) so there is no need to distinguish between the two. [kzak@redhat.com: - better handle realloc() errors] Signed-off-by: Tobias Klauser Signed-off-by: Karel Zak --- mount/lomount.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mount/lomount.c b/mount/lomount.c index 54b9f8e9..03aae4b2 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -258,11 +258,16 @@ loop_scandir(const char *dirname, int **ary, int hasprefix) if (n == -1 || n < NLOOPS_DEFAULT) continue; if (count + 1 > arylen) { + int *tmp; + arylen += 1; - *ary = *ary ? realloc(*ary, arylen * sizeof(int)) : - malloc(arylen * sizeof(int)); - if (!*ary) + + tmp = realloc(*ary, arylen * sizeof(int)); + if (!tmp) { + free(*ary); return -1; + } + *ary = tmp; } (*ary)[count++] = n; } -- cgit v1.2.3 From 3a788d773b13078ce8c87247e7f5f556646203b3 Mon Sep 17 00:00:00 2001 From: Dima Kogan Date: Sat, 14 Aug 2010 02:15:47 -0700 Subject: tailf: fixed timing issue that could cause duplicate data output The issue is that in roll_file() we fstat() to find the file size, then read() as much data as we can and then use the previously saved file size to mark our position. The bug occurs if we read past the file size reported by fstat() because more data has arrived while we were reading it. The attached patch uses the current file position as the location marker instead, with some extra logic to handle tailing truncated files. [kzak@redhat.com: - fix coding style] Signed-off-by: Dima Kogan Signed-off-by: Karel Zak --- text-utils/tailf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/text-utils/tailf.c b/text-utils/tailf.c index 75998ce7..dc18b2a6 100644 --- a/text-utils/tailf.c +++ b/text-utils/tailf.c @@ -88,6 +88,7 @@ roll_file(const char *filename, off_t *size) char buf[BUFSIZ]; int fd; struct stat st; + off_t pos; if (!(fd = open(filename, O_RDONLY))) err(EXIT_FAILURE, _("cannot open \"%s\" for read"), filename); @@ -111,8 +112,16 @@ roll_file(const char *filename, off_t *size) } fflush(stdout); } + + pos = lseek(fd, 0, SEEK_CUR); + + /* If we've successfully read something, use the file position, this + * avoids data duplication. If we read nothing or hit an error, reset + * to the reported size, this handles truncated files. + */ + *size = (pos != -1 && pos != *size) ? pos : st.st_size; + close(fd); - *size = st.st_size; } static void -- cgit v1.2.3 From 9b8d4d5f1818ede8f38eca74aef30a62e8e70ef3 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Tue, 17 Aug 2010 10:02:00 -0400 Subject: lscpu: add byte order and bogoMIPS information Signed-off-by: Davidlohr Bueso Signed-off-by: Karel Zak --- sys-utils/lscpu.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 58cd869d..ac66d2ec 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "cpuset.h" #include "nls.h" @@ -97,6 +98,7 @@ struct lscpu_desc { int virtype; /* VIRT_PARA|FULL|NONE ? */ char *mhz; char *stepping; + char *bogomips; char *flags; int mode; /* rm, lm or/and tm */ @@ -366,6 +368,7 @@ read_basicinfo(struct lscpu_desc *desc) else if (lookup(buf, "stepping", &desc->stepping)) ; else if (lookup(buf, "cpu MHz", &desc->mhz)) ; else if (lookup(buf, "flags", &desc->flags)) ; + else if (lookup(buf, "bogomips", &desc->bogomips)) ; else continue; } @@ -812,7 +815,13 @@ print_readable(struct lscpu_desc *desc, int hex) *(p - 2) = '\0'; print_s(_("CPU op-mode(s):"), buf); } - +#ifdef __BYTE_ORDER +#if (__BYTE_ORDER == __LITTLE_ENDIAN) + print_s(_("Byte Order:"), "Little Endian"); +#else + print_s(_("Byte Order:"), "Big Endian"); +#endif +#endif print_n(_("CPU(s):"), desc->ncpus); print_cpuset(hex ? _("On-line CPU(s) mask:") : @@ -858,6 +867,8 @@ print_readable(struct lscpu_desc *desc, int hex) print_s(_("Stepping:"), desc->stepping); if (desc->mhz) print_s(_("CPU MHz:"), desc->mhz); + if (desc->bogomips) + print_s(_("BogoMIPS:"), desc->bogomips); if (desc->virtflag) { if (!strcmp(desc->virtflag, "svm")) print_s(_("Virtualization:"), "AMD-V"); -- cgit v1.2.3 From 2d4f58856ab9cbd328369c9c022f1629b9688a88 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 20 Aug 2010 11:08:48 +0300 Subject: docs: make it easier to find mail list address AUTHORS doesn't really have the mail list info, but README does. Mention it in README.devel. Signed-off-by: Alexander Shishkin --- README.devel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.devel b/README.devel index 3ffc9c08..fdfa2644 100644 --- a/README.devel +++ b/README.devel @@ -17,7 +17,7 @@ AUTOTOOLS: PATCHES: * send your patches to the mailing list or to the upstream maintainer - (see the AUTHORS file) + (see the AUTHORS and README files) * diff -u -- cgit v1.2.3 From e61332c3715f9f2df2fa3abbd79dee095e2652ca Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 20 Aug 2010 21:02:29 +0200 Subject: tests: fix blkid MD test (missing tailing whitespaces) Signed-off-by: Karel Zak --- tests/expected/blkid/md-raid0-whole | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/expected/blkid/md-raid0-whole b/tests/expected/blkid/md-raid0-whole index a13647de..2e0b824a 100644 --- a/tests/expected/blkid/md-raid0-whole +++ b/tests/expected/blkid/md-raid0-whole @@ -12,14 +12,14 @@ Command (m for help): Command action e extended p primary partition (1-4) Partition number (1-4, default 1): First sector (2048-204543, default 2048): Using default value 2048 -Last sector, +sectors or +size{K,M,G} (2048-204543, default 204543): +Last sector, +sectors or +size{K,M,G} (2048-204543, default 204543): Command (m for help): Command action e extended p primary partition (1-4) Partition number (1-4, default 2): First sector (22528-204543, default 22528): Using default value 22528 Last sector, +sectors or +size{K,M,G} (22528-204543, default 204543): Using default value 204543 -Command (m for help): +Command (m for help): Disk /dev/md8: 104 MB, 104726528 bytes 2 heads, 4 sectors/track, 25568 cylinders, total 204544 sectors Units = sectors of 1 * 512 = 512 bytes -- cgit v1.2.3 From 5d4ba40ddcf8e0edb3e595e398d22af67074cebe Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 20 Aug 2010 21:15:51 +0200 Subject: lscpu: support sysfs without cpu/online file Signed-off-by: Karel Zak --- sys-utils/lscpu.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index ac66d2ec..027a2982 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -402,7 +402,8 @@ read_basicinfo(struct lscpu_desc *desc) maxcpus = desc->ncpus > 2048 ? desc->ncpus : 2048; /* get mask for online CPUs */ - desc->online = path_cpulist(_PATH_SYS_SYSTEM "/cpu/online"); + if (path_exist(_PATH_SYS_SYSTEM "/cpu/online")) + desc->online = path_cpulist(_PATH_SYS_SYSTEM "/cpu/online"); } static int @@ -709,7 +710,7 @@ print_parsable(struct lscpu_desc *desc) for (i = 0; i < desc->ncpus; i++) { - if (!is_cpu_online(desc, i)) + if (desc->online && !is_cpu_online(desc, i)) continue; /* #CPU */ @@ -824,11 +825,12 @@ print_readable(struct lscpu_desc *desc, int hex) #endif print_n(_("CPU(s):"), desc->ncpus); - print_cpuset(hex ? _("On-line CPU(s) mask:") : - _("On-line CPU(s) list:"), - desc->online, hex); + if (desc->online) + print_cpuset(hex ? _("On-line CPU(s) mask:") : + _("On-line CPU(s) list:"), + desc->online, hex); - if (CPU_COUNT_S(setsize, desc->online) != desc->ncpus) { + if (desc->online && CPU_COUNT_S(setsize, desc->online) != desc->ncpus) { cpu_set_t *set; /* Linux kernel provides cpuset of off-line CPUs that contains @@ -952,7 +954,7 @@ int main(int argc, char *argv[]) read_basicinfo(desc); for (i = 0; i < desc->ncpus; i++) { - if (!is_cpu_online(desc, i)) + if (desc->online && !is_cpu_online(desc, i)) continue; read_topology(desc, i); read_cache(desc, i); -- cgit v1.2.3 From 295b8bb906b7c3c14edb24b226331f6ddfd04427 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 20 Aug 2010 21:29:04 +0200 Subject: tests: update lscpu tests Signed-off-by: Karel Zak --- tests/expected/lscpu/lscpu-i386-amdshanghai | 1 + tests/expected/lscpu/lscpu-i386-dellpe700 | 1 + tests/expected/lscpu/lscpu-i386-intels5000phb | 1 + tests/expected/lscpu/lscpu-x86_64-dellr710 | 1 + tests/expected/lscpu/lscpu-x86_64-hpdl585 | 1 + tests/expected/lscpu/lscpu-x86_64-ibme326m | 1 + tests/expected/lscpu/lscpu-x86_64-necem14 | 1 + tests/ts/lscpu/lscpu | 3 +++ 8 files changed, 10 insertions(+) diff --git a/tests/expected/lscpu/lscpu-i386-amdshanghai b/tests/expected/lscpu/lscpu-i386-amdshanghai index 4e300885..5f2d74ec 100644 --- a/tests/expected/lscpu/lscpu-i386-amdshanghai +++ b/tests/expected/lscpu/lscpu-i386-amdshanghai @@ -8,6 +8,7 @@ CPU family: 16 Model: 4 Stepping: 0 CPU MHz: 1995.158 +BogoMIPS: 3989.99 Virtualization: AMD-V L1d cache: 512K L1i cache: 512K diff --git a/tests/expected/lscpu/lscpu-i386-dellpe700 b/tests/expected/lscpu/lscpu-i386-dellpe700 index 5b7562b6..d1d95c79 100644 --- a/tests/expected/lscpu/lscpu-i386-dellpe700 +++ b/tests/expected/lscpu/lscpu-i386-dellpe700 @@ -8,6 +8,7 @@ CPU family: 15 Model: 2 Stepping: 9 CPU MHz: 3391.773 +BogoMIPS: 6781.99 # The following is the parsable format, which can be fed to other # programs. Each different item in every column has an unique ID diff --git a/tests/expected/lscpu/lscpu-i386-intels5000phb b/tests/expected/lscpu/lscpu-i386-intels5000phb index 0436aae5..24ca496a 100644 --- a/tests/expected/lscpu/lscpu-i386-intels5000phb +++ b/tests/expected/lscpu/lscpu-i386-intels5000phb @@ -8,6 +8,7 @@ CPU family: 6 Model: 15 Stepping: 7 CPU MHz: 1596.044 +BogoMIPS: 3191.91 Virtualization: VT-x L1d cache: 32K L1i cache: 32K diff --git a/tests/expected/lscpu/lscpu-x86_64-dellr710 b/tests/expected/lscpu/lscpu-x86_64-dellr710 index 43679dc4..d436f22f 100644 --- a/tests/expected/lscpu/lscpu-x86_64-dellr710 +++ b/tests/expected/lscpu/lscpu-x86_64-dellr710 @@ -9,6 +9,7 @@ CPU family: 6 Model: 26 Stepping: 5 CPU MHz: 2527.073 +BogoMIPS: 5053.32 Virtualization: VT-x L1d cache: 32K L1i cache: 32K diff --git a/tests/expected/lscpu/lscpu-x86_64-hpdl585 b/tests/expected/lscpu/lscpu-x86_64-hpdl585 index 54a1a242..2dc36c06 100644 --- a/tests/expected/lscpu/lscpu-x86_64-hpdl585 +++ b/tests/expected/lscpu/lscpu-x86_64-hpdl585 @@ -9,6 +9,7 @@ CPU family: 16 Model: 2 Stepping: 3 CPU MHz: 2210.188 +BogoMIPS: 4420.50 Virtualization: AMD-V L1d cache: 512K L1i cache: 512K diff --git a/tests/expected/lscpu/lscpu-x86_64-ibme326m b/tests/expected/lscpu/lscpu-x86_64-ibme326m index ccc64a07..98aea983 100644 --- a/tests/expected/lscpu/lscpu-x86_64-ibme326m +++ b/tests/expected/lscpu/lscpu-x86_64-ibme326m @@ -9,6 +9,7 @@ CPU family: 15 Model: 33 Stepping: 2 CPU MHz: 1995.058 +BogoMIPS: 3989.41 L1d cache: 1024K L1i cache: 1024K L2 cache: 1024K diff --git a/tests/expected/lscpu/lscpu-x86_64-necem14 b/tests/expected/lscpu/lscpu-x86_64-necem14 index c823f7e7..d3c4f1ba 100644 --- a/tests/expected/lscpu/lscpu-x86_64-necem14 +++ b/tests/expected/lscpu/lscpu-x86_64-necem14 @@ -9,6 +9,7 @@ CPU family: 15 Model: 4 Stepping: 3 CPU MHz: 3790.599 +BogoMIPS: 7579.94 L1d cache: 16K L2 cache: 2048K NUMA node0 CPU(s): 0,1 diff --git a/tests/ts/lscpu/lscpu b/tests/ts/lscpu/lscpu index 2c7f2a45..a3c6e492 100755 --- a/tests/ts/lscpu/lscpu +++ b/tests/ts/lscpu/lscpu @@ -40,6 +40,9 @@ for dump in $(ls $TS_SELF/dumps/*.tar.gz | sort); do "${TS_CMD_LSCPU}" -p -s "${dumpdir}/${name}" \ >>"${TS_OUTPUT}" 2>&1 + # LE/BE depends on binary + sed -i -e '/Byte Order:.*/d' $TS_OUTPUT + ts_finalize_subtest done -- cgit v1.2.3 From fab1c0463a7147599e5878e307be10e358a77074 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 23 Aug 2010 11:06:08 +0200 Subject: lib: fix syntax error in blkdev.c Reported-by: Tuco Signed-off-by: Karel Zak --- lib/blkdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/blkdev.c b/lib/blkdev.c index 7d00324d..67c4a1ac 100644 --- a/lib/blkdev.c +++ b/lib/blkdev.c @@ -104,7 +104,7 @@ blkdev_get_size(int fd, unsigned long long *bytes) #ifdef DIOCGMEDIASIZE /* FreeBSD */ if (ioctl(fd, DIOCGMEDIASIZE, bytes) >= 0) - return 0 + return 0; #endif #ifdef FDGETPRM -- cgit v1.2.3 From 06023c2e97ee6a8cd5dbb419c3aadfaae5b253f2 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 23 Aug 2010 12:11:26 +0200 Subject: fdisk: don't keep internally device size in 512-byte sectors All fdisk code uses sector_size variable, so there should not be an exception where we use 512-byte sectors. Signed-off-by: Karel Zak --- fdisk/fdisk.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index af95bcc6..93eece6e 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -219,12 +219,11 @@ unsigned long long sector_offset = 1, extended_offset = 0, sectors; unsigned int heads, cylinders, sector_size = DEFAULT_SECTOR_SIZE, - sector_factor = 1, user_set_sector_size = 0, units_per_sector = 1, display_in_cyl_units = 0; -unsigned long long total_number_of_sectors; /* (!) 512-byte sectors */ +unsigned long long total_number_of_sectors; /* in logical sectors */ unsigned long grain = DEFAULT_SECTOR_SIZE, io_size = DEFAULT_SECTOR_SIZE, min_io_size = DEFAULT_SECTOR_SIZE, @@ -772,7 +771,8 @@ void update_units(void) static void warn_limits(void) { if (total_number_of_sectors > UINT_MAX && !nowarn) { - int giga = (total_number_of_sectors << 9) / 1000000000; + unsigned long long bytes = total_number_of_sectors * sector_size; + int giga = bytes / 1000000000; int hectogiga = (giga + 50) / 100; fprintf(stderr, _("\n" @@ -781,7 +781,7 @@ warn_limits(void) { "larger than (%llu bytes) for %d-byte sectors. Use parted(1) and GUID \n" "partition table format (GPT).\n\n"), hectogiga / 10, hectogiga % 10, - total_number_of_sectors << 9, + bytes, (unsigned long long ) UINT_MAX * sector_size, sector_size); } @@ -1122,10 +1122,9 @@ update_sector_offset(void) void get_geometry(int fd, struct geom *g) { - unsigned long long llcyls; + unsigned long long llcyls, nsects = 0; get_topology(fd); - sector_factor = sector_size / 512; guess_device_type(fd); heads = cylinders = sectors = 0; kern_heads = kern_sectors = 0; @@ -1141,12 +1140,13 @@ get_geometry(int fd, struct geom *g) { pt_sectors ? pt_sectors : kern_sectors ? kern_sectors : 63; - if (blkdev_get_sectors(fd, &total_number_of_sectors) == -1) - total_number_of_sectors = 0; + /* get number of 512-byte sectors, and convert it the real sectors */ + if (blkdev_get_sectors(fd, &nsects) == 0) + total_number_of_sectors = (nsects / (sector_size >> 9)); update_sector_offset(); - llcyls = total_number_of_sectors / (heads * sectors * sector_factor); + llcyls = total_number_of_sectors / (heads * sectors); cylinders = llcyls; if (cylinders != llcyls) /* truncated? */ cylinders = ~0; @@ -1889,7 +1889,7 @@ check_alignment(unsigned long long lba, int partition) static void list_disk_geometry(void) { - long long bytes = (total_number_of_sectors << 9); + unsigned long long bytes = total_number_of_sectors * sector_size; long megabytes = bytes/1000000; if (megabytes < 10000) @@ -1897,14 +1897,13 @@ list_disk_geometry(void) { disk_device, megabytes, bytes); else { long hectomega = (megabytes + 50) / 100; - printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"), + printf(_("\nDisk %s: %ld.%ld GB, %llu bytes\n"), disk_device, hectomega / 10, hectomega % 10, bytes); } printf(_("%d heads, %llu sectors/track, %d cylinders"), heads, sectors, cylinders); if (units_per_sector == 1) - printf(_(", total %llu sectors"), - total_number_of_sectors / sector_factor); + printf(_(", total %llu sectors"), total_number_of_sectors); printf("\n"); printf(_("Units = %s of %d * %d = %d bytes\n"), str_units(PLURAL), @@ -2213,7 +2212,7 @@ static void verify(void) { int i, j; unsigned long long total = 1; - unsigned long long n_sectors = (total_number_of_sectors / sector_factor); + unsigned long long n_sectors = total_number_of_sectors; unsigned long long first[partitions], last[partitions]; struct partition *p; @@ -2327,7 +2326,7 @@ add_partition(int n, int sys) { if (display_in_cyl_units || !total_number_of_sectors) llimit = heads * sectors * cylinders - 1; else - llimit = (total_number_of_sectors / sector_factor) - 1; + llimit = total_number_of_sectors - 1; limit = llimit; if (limit != llimit) limit = 0x7fffffff; -- cgit v1.2.3 From 7d22c8e27c4720010d464b7b6c677bc305d74e35 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 23 Aug 2010 13:13:36 +0200 Subject: fdisk: fix alignment check for non-512-byte logical sectors # modprobe scsi_debug dev_size_mb=1024 sector_size=4096 # fdisk /dev/sdb Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4, default 1): Using default value 1 First sector (256-262143, default 256): 257 Last sector, +sectors or +size{K,M,G} (257-262143, default 262143): +100M Command (m for help): p Disk /dev/sdb: 1073 MB, 1073741824 bytes 32 heads, 32 sectors/track, 256 cylinders, total 262144 sectors Units = sectors of 1 * 4096 = 4096 bytes Sector size (logical/physical): 4096 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 262144 bytes Disk identifier: 0x16db2bb0 Device Boot Start End Blocks Id System /dev/sdb1 257 25855 102396 83 Linux Partition 1 does not start on physical sector boundary. ^^^^^^^^ The warning is nonsense. The logical and physical sector size is the same. It means that every LBA is always aligned to physical sector boundary. Note that this bug does not mean that fdisk produces unaligned partitions. The problem is that fdisk forces to use bigger gaps between aligned LBAs, for example: correctly aligned LBA are: 256, 257, 258, ... [N+1] fdisk assumes: 256, 264, 272, ... [N+(sector_size/512)] Reported-by: JOB NELSON Signed-off-by: Karel Zak --- fdisk/fdisk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c index 93eece6e..68293213 100644 --- a/fdisk/fdisk.c +++ b/fdisk/fdisk.c @@ -659,7 +659,7 @@ static int lba_is_aligned(unsigned long long lba) { unsigned int granularity = max(phy_sector_size, min_io_size); - unsigned long long offset = (lba << 9) & (granularity - 1); + unsigned long long offset = (lba * sector_size) & (granularity - 1); return !((granularity + alignment_offset - offset) & (granularity - 1)); } -- cgit v1.2.3 From 1519ab5ffca4ec4be5ae36556e2e608c188d8f60 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 24 Aug 2010 11:43:21 +0200 Subject: blockdev: add BLKDISCARDZEROES Signed-off-by: Karel Zak --- disk-utils/blockdev.c | 6 ++++++ include/blkdev.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/disk-utils/blockdev.c b/disk-utils/blockdev.c index cf594d12..089405e9 100644 --- a/disk-utils/blockdev.c +++ b/disk-utils/blockdev.c @@ -74,6 +74,12 @@ struct bdc bdcms[] = .argtype = ARG_INT, .argval = -1, .help = N_("get read-only") + },{ + IOCTL_ENTRY(BLKDISCARDZEROES), + .name = "--getdiscardzeroes", + .argtype = ARG_UINT, + .argval = -1, + .help = N_("get discard zeroes support status") },{ IOCTL_ENTRY(BLKSSZGET), .name = "--getss", diff --git a/include/blkdev.h b/include/blkdev.h index 0eea01cd..2179c6ed 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -33,6 +33,7 @@ #endif /* BLKROSET && __linux__ */ + #ifdef APPLE_DARWIN #define BLKGETSIZE DKIOCGETBLOCKCOUNT32 #endif @@ -45,6 +46,11 @@ #define BLKPBSZGET _IO(0x12,123) #endif +/* discard zeroes support, introduced in 2.6.33 (commait 98262f27) */ +#ifndef BLKDISCARDZEROES +#define BLKDISCARDZEROES _IO(0x12,124) +#endif + #ifndef FIFREEZE #define FIFREEZE _IOWR('X', 119, int) /* Freeze */ #define FITHAW _IOWR('X', 120, int) /* Thaw */ -- cgit v1.2.3 From 9ef30d61783eb738040eefb1bbacdc50b39bf7d5 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 24 Aug 2010 12:04:24 +0200 Subject: include: cleanup blkdev.h Signed-off-by: Karel Zak --- include/blkdev.h | 79 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/include/blkdev.h b/include/blkdev.h index 2179c6ed..5344a2ba 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -8,52 +8,57 @@ #define DEFAULT_SECTOR_SIZE 512 -#if !defined(BLKROSET) && defined(__linux__) - -#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ -#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ -#define BLKRRPART _IO(0x12,95) /* re-read partition table */ -#define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */ -#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ -#define BLKRASET _IO(0x12,98) /* set read ahead for block device */ -#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */ -#define BLKFRASET _IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */ -#define BLKFRAGET _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */ -#define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */ -#define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */ -#define BLKSSZGET _IO(0x12,104)/* get block device sector size */ +#ifdef __linux__ +/* very basic ioclts, should be available everywhere */ +# ifndef BLKROSET +# define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */ +# define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */ +# define BLKRRPART _IO(0x12,95) /* re-read partition table */ +# define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */ +# define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */ +# define BLKRASET _IO(0x12,98) /* set read ahead for block device */ +# define BLKRAGET _IO(0x12,99) /* get current read ahead setting */ +# define BLKFRASET _IO(0x12,100) /* set filesystem (mm/filemap.c) read-ahead */ +# define BLKFRAGET _IO(0x12,101) /* get filesystem (mm/filemap.c) read-ahead */ +# define BLKSECTSET _IO(0x12,102) /* set max sectors per request (ll_rw_blk.c) */ +# define BLKSECTGET _IO(0x12,103) /* get max sectors per request (ll_rw_blk.c) */ +# define BLKSSZGET _IO(0x12,104) /* get block device sector size */ /* ioctls introduced in 2.2.16, removed in 2.5.58 */ -#define BLKELVGET _IOR(0x12,106,size_t) /* elevator get */ -#define BLKELVSET _IOW(0x12,107,size_t) /* elevator set */ +# define BLKELVGET _IOR(0x12,106,size_t) /* elevator get */ +# define BLKELVSET _IOW(0x12,107,size_t) /* elevator set */ -#define BLKBSZGET _IOR(0x12,112,size_t) -#define BLKBSZSET _IOW(0x12,113,size_t) -#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ +# define BLKBSZGET _IOR(0x12,112,size_t) +# define BLKBSZSET _IOW(0x12,113,size_t) +# endif /* !BLKROSET */ -#endif /* BLKROSET && __linux__ */ +# ifndef BLKGETSIZE64 +# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ +# endif +/* block device topology ioctls, introduced in 2.6.32 (commit ac481c20) */ +# ifndef BLKIOMIN +# define BLKIOMIN _IO(0x12,120) +# define BLKIOOPT _IO(0x12,121) +# define BLKALIGNOFF _IO(0x12,122) +# define BLKPBSZGET _IO(0x12,123) +# endif -#ifdef APPLE_DARWIN -#define BLKGETSIZE DKIOCGETBLOCKCOUNT32 -#endif +/* discard zeroes support, introduced in 2.6.33 (commit 98262f27) */ +# ifndef BLKDISCARDZEROES +# define BLKDISCARDZEROES _IO(0x12,124) +# endif -/* block device topology ioctls, introduced in 2.6.32 */ -#ifndef BLKIOMIN -#define BLKIOMIN _IO(0x12,120) -#define BLKIOOPT _IO(0x12,121) -#define BLKALIGNOFF _IO(0x12,122) -#define BLKPBSZGET _IO(0x12,123) -#endif +/* filesystem freeze, introduced in 2.6.29 (commit fcccf502) */ +# ifndef FIFREEZE +# define FIFREEZE _IOWR('X', 119, int) /* Freeze */ +# define FITHAW _IOWR('X', 120, int) /* Thaw */ +# endif -/* discard zeroes support, introduced in 2.6.33 (commait 98262f27) */ -#ifndef BLKDISCARDZEROES -#define BLKDISCARDZEROES _IO(0x12,124) -#endif +#endif /* __linux */ -#ifndef FIFREEZE -#define FIFREEZE _IOWR('X', 119, int) /* Freeze */ -#define FITHAW _IOWR('X', 120, int) /* Thaw */ +#ifdef APPLE_DARWIN +# define BLKGETSIZE DKIOCGETBLOCKCOUNT32 #endif #ifndef HDIO_GETGEO -- cgit v1.2.3 From 455fdf4af8d0bc4df3f0474770848dfc97a4f51e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 24 Aug 2010 12:59:41 +0200 Subject: blockdev: sync man page with code Signed-off-by: Karel Zak --- disk-utils/blockdev.8 | 120 +++++++++++++++++++++++--------------------------- disk-utils/blockdev.c | 10 ++--- 2 files changed, 61 insertions(+), 69 deletions(-) diff --git a/disk-utils/blockdev.8 b/disk-utils/blockdev.8 index fa01da54..c3d5dfd7 100644 --- a/disk-utils/blockdev.8 +++ b/disk-utils/blockdev.8 @@ -3,90 +3,82 @@ .\" Copyright 2007 Karel Zak .\" .\" May be distributed under the GNU General Public License -.TH BLOCKDEV 8 "Jun 2007" "" +.TH BLOCKDEV 8 "Aug 2010" "" .SH NAME blockdev \- call block device ioctls from the command line .SH SYNOPSIS .B blockdev -.RI [ options ] -.I commands devices +.RB [ \-q ] +.RB [ \-v ] +.IR command +.RI [ command ...] +.IR device +.RI [ device ...] .br .B blockdev .B \-\-report -.RI [ devices ] +.RI [ device ...] .SH DESCRIPTION The utility .B blockdev allows one to call block device ioctls from the command line. .SH OPTIONS -.TP -.B \-V +.IP "\fB\-V\fP" Print version and exit. -.TP -.B \-q +.IP "\fB\-q\fP" Be quiet. -.TP -.B \-v +.IP "\fB\-v\fP" Be verbose. -.TP -.B \-\-report -Print a report for -.IR devices . -Note that the partition StartSec is in 512-byte sectors. +.IP "\fB\-\-report\fP" +Print a report for the specified device. It is possible to give multiple +devices. If none is given, all devices which appear in /proc/partitions are +shown. Note that the partition StartSec is in 512-byte sectors. .SH COMMANDS -.TP -.B \--setro -Set read-only. -.TP -.B \--setrw -Set read-write. -.TP -.B \--getro -Get read-only. Print 1 if the device is read-only, 0 otherwise. -.TP -.B \--getss -Print sectorsize in bytes - usually 512. -.TP -.B \--getbsz +It is possible to give multiple devices and multiple commands. +.IP "\fB\-\-flushbufs\fP" +Flush buffers. +.IP "\fB\-\-getalignoff\fP" +Get alignment offset. +.IP "\fB\-\-getbsz\fP" Print blocksize in bytes. -.TP -.BI \--setbsz " N" -Set blocksize to -.I N -bytes. -.TP -.B \--getsize -Print device size in sectors (BLKGETSIZE). Deprecated in favor of the -.B \--getsz -option. -.TP -.B \--getsize64 -Print device size in bytes (BLKGETSIZE64) -.TP -.B \--getsz -Get size in 512-byte sectors (BLKGETSIZE64 / 512). -.TP -.BI \--setra " N" -Set readahead to -.I N -512-byte sectors. -.TP -.B \--getra +.IP "\fB\-\-getdiscardzeroes\fP" +Get discard zeroes support status. +.IP "\fB\-\-getfra\fP" +Get filesystem readahead in 512-byte sectors. +.IP "\fB\-\-getiomin\fP" +Get minimum I/O size. +.IP "\fB\-\-getioopt\fP" +Get optimal I/O size. +.IP "\fB\-\-getmaxsect\fP" +Get max sectors per request +.IP "\fB\-\-getpbsz\fP" +Get physical block (sector) size. +.IP "\fB\-\-getra\fP" Print readahead (in 512-byte sectors). -.TP -.BI \--setfra " N" +.IP "\fB\-\-getro\fP" +Get read-only. Print 1 if the device is read-only, 0 otherwise. +.IP "\fB\-\-getsize64\fP" +Print device size in bytes. +.IP "\fB\-\-getsize\fP" +Print device size (32-bit!) in sectors. Deprecated in favor of the --getsz option. +.IP "\fB\-\-getss\fP" +Print sectorsize in bytes - usually 512. +.IP "\fB\-\-getsz\fP" +Get size in 512-byte sectors. +.IP "\fB\-\-rereadpt\fP" +Seread partition table +.IP "\fB\-\-setbsz\fP \fIbytes\fP" +Set blocksize. +.IP "\fB\-\-setfra\fP \fIsectors\fP" Set filesystem readahead (same like --setra on 2.6 kernels). -.TP -.B \--getfra -Get filesystem readahead. -.TP -.B \--flushbufs -Flush buffers. -.TP -.B \--rereadpt -Reread partition table. +.IP "\fB\-\-setra\fP \fIsectors\fP" +Set readahead (in 512-byte sectors). +.IP "\fB\-\-setro\fP" +Set read-only. +.IP "\fB\-\-setrw\fP" +Set read-write. .SH AUTHOR -blockdev was written by Andries E. Brouwer. +blockdev was written by Andries E. Brouwer and rewrittent by Karel Zak. .SH AVAILABILITY The blockdev command is part of the util-linux-ng package and is available from ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/. diff --git a/disk-utils/blockdev.c b/disk-utils/blockdev.c index 089405e9..27b1a0a2 100644 --- a/disk-utils/blockdev.c +++ b/disk-utils/blockdev.c @@ -109,7 +109,7 @@ struct bdc bdcms[] = .name = "--getalignoff", .argtype = ARG_INT, .argval = -1, - .help = N_("get alignment offset") + .help = N_("get alignment offset in bytes") },{ IOCTL_ENTRY(BLKSECTGET), .name = "--getmaxsect", @@ -125,7 +125,7 @@ struct bdc bdcms[] = },{ IOCTL_ENTRY(BLKBSZSET), .name = "--setbsz", - .argname = "BLOCKSIZE", + .argname = "", .argtype = ARG_INT, .flags = FL_NORESULT, .help = N_("set blocksize") @@ -134,7 +134,7 @@ struct bdc bdcms[] = .name = "--getsize", .argtype = ARG_ULONG, .argval = -1, - .help = N_("get 32-bit sector count") + .help = N_("get 32-bit sector count (deprecated, use --getsz)") },{ IOCTL_ENTRY(BLKGETSIZE64), .name = "--getsize64", @@ -144,7 +144,7 @@ struct bdc bdcms[] = },{ IOCTL_ENTRY(BLKRASET), .name = "--setra", - .argname = "READAHEAD", + .argname = "", .argtype = ARG_INT, .flags = FL_NOPTR | FL_NORESULT, .help = N_("set readahead") @@ -157,7 +157,7 @@ struct bdc bdcms[] = },{ IOCTL_ENTRY(BLKFRASET), .name = "--setfra", - .argname = "FSREADAHEAD", + .argname = "", .argtype = ARG_INT, .flags = FL_NOPTR | FL_NORESULT, .help = N_("set filesystem readahead") -- cgit v1.2.3 From 5adaf9f120131f030ce15c5a312746059608e762 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Mon, 23 Aug 2010 10:17:36 -0400 Subject: mount: Add more pseudo filesystems. Signed-off-by: Davidlohr Bueso --- mount/sundries.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mount/sundries.c b/mount/sundries.c index 1d9eb88e..98f46949 100644 --- a/mount/sundries.c +++ b/mount/sundries.c @@ -256,7 +256,9 @@ is_pseudo_fs(const char *type) streq(type, "cgroup") || streq(type, "cpuset") || streq(type, "rpc_pipefs") || - streq(type, "devpts")) + streq(type, "devpts") || + streq(type, "securityfs") || + streq(type, "debugfs")) return 1; return 0; } -- cgit v1.2.3 From 0828125895f7323e39b87673dbdbef4c70da5fdb Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 27 Aug 2010 12:22:27 +0200 Subject: mount: sanity check mount flags for MS_PROPAGATION mount(8) reuses mount flags from fstab/mtab, the problem is that for MS_PROPAGATION operations kernel incorrectly evaluates mount flags if the flags contains any non-propagation stuff (e.g. MS_RDONLY). For example --make-shared on read-only FS: # strace -e mount mount --make-shared /mnt/test mount("/dev/sda1", "/mnt/test", "none", MS_RDONLY|MS_SHARED, NULL) = 0 must be: # strace -e mount mount --make-shared /mnt/test mount("/dev/sda1", "/mnt/test", "none", MS_SHARED, NULL) = 0 Reported-by: Valerie Aurora Signed-off-by: Karel Zak --- mount/mount.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mount/mount.c b/mount/mount.c index 2e819e95..f2b6ee23 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -491,9 +491,11 @@ parse_opts (const char *options, int *flags, char **extra_opts) { if (readwrite) *flags &= ~MS_RDONLY; - if (mounttype & MS_PROPAGATION) - *flags &= ~MS_BIND; *flags |= mounttype; + + /* The propagation flags should not be used together with any other flags */ + if (*flags & MS_PROPAGATION) + *flags &= MS_PROPAGATION; } /* Try to build a canonical options string. */ -- cgit v1.2.3 From dc0a335554eafa643c7fd123d99e14df72c515c3 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 27 Aug 2010 16:58:44 +0200 Subject: mount: handle filesystems with subtype Linux can handle filesystem types with "MAINTYPE.SUBTYPE" format, where the main type determines the actual filesystem driver while the subtype can be interpreted by the filesystem itself. When searching for mount helpers mount(8) and umount(8) should also interpret such types, falling back to (u)mount.MAINTYPE if (u)mount.MAINTYPE.SUBTYPE doesn't exist. This patch implements this, passing the type with "-t TYPE" to the mount program in this case. Reported-by: Josef Bacik Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=625064 Signed-off-by: Miklos Szeredi --- mount/mount.c | 19 ++++++++++++++++--- mount/umount.c | 17 +++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/mount/mount.c b/mount/mount.c index f2b6ee23..84986e36 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -664,13 +664,22 @@ check_special_mountprog(const char *spec, const char *node, const char *type, in path = strtok(search_path, ":"); while (path) { + int type_opt = 0; + res = snprintf(mountprog, sizeof(mountprog), "%s/mount.%s", path, type); path = strtok(NULL, ":"); if (res >= sizeof(mountprog) || res < 0) continue; - if (stat(mountprog, &statbuf)) + res = stat(mountprog, &statbuf); + if (res == -1 && errno == ENOENT && strchr(type, '.')) { + /* If type ends with ".subtype" try without it */ + *strrchr(mountprog, '.') = '\0'; + type_opt = 1; + res = stat(mountprog, &statbuf); + } + if (res) continue; if (verbose) @@ -678,7 +687,7 @@ check_special_mountprog(const char *spec, const char *node, const char *type, in switch (fork()) { case 0: { /* child */ - char *oo, *mountargs[10]; + char *oo, *mountargs[12]; int i = 0; if (setgid(getgid()) < 0) @@ -703,7 +712,11 @@ check_special_mountprog(const char *spec, const char *node, const char *type, in mountargs[i++] = "-o"; /* 8 */ mountargs[i++] = oo; /* 9 */ } - mountargs[i] = NULL; /* 10 */ + if (type_opt) { + mountargs[i++] = "-t"; /* 10 */ + mountargs[i++] = (char *) type; /* 11 */ + } + mountargs[i] = NULL; /* 12 */ if (verbose > 2) { i = 0; diff --git a/mount/umount.c b/mount/umount.c index 5bd53604..0ad7c5f9 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -103,11 +103,20 @@ check_special_umountprog(const char *spec, const char *node, return 0; if (strlen(type) < 100) { + int type_opt = 0; + sprintf(umountprog, "/sbin/umount.%s", type); - if (stat(umountprog, &statbuf) == 0) { + res = stat(umountprog, &statbuf); + if (res == -1 && errno == ENOENT && strchr(type, '.')) { + /* If type ends with ".subtype" try without it */ + *strrchr(umountprog, '.') = '\0'; + type_opt = 1; + res = stat(umountprog, &statbuf); + } + if (res == 0) { res = fork(); if (res == 0) { - char *umountargs[8]; + char *umountargs[10]; int i = 0; if(setgid(getgid()) < 0) @@ -128,6 +137,10 @@ check_special_umountprog(const char *spec, const char *node, umountargs[i++] = "-v"; if (remount) umountargs[i++] = "-r"; + if (type_opt) { + umountargs[i++] = "-t"; + umountargs[i++] = (char *) type; + } umountargs[i] = NULL; execv(umountprog, umountargs); exit(1); /* exec failed */ -- cgit v1.2.3 From 8eff6643e191b5aebebdc33d091c5f4f1e606e2c Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 27 Aug 2010 20:42:16 +0200 Subject: mount: add info about type.subtype to /sbin/mount. API description Signed-off-by: Karel Zak --- mount/mount.8 | 7 +++++-- mount/umount.8 | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mount/mount.8 b/mount/mount.8 index 1e8a08e4..2fe0db8d 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -2632,10 +2632,13 @@ The syntax of external mount helpers is: .RB [ \-sfnv ] .RB [ \-o .IR options ] +.RB [ \-t +.IR type.subtype ] .RE -where the is filesystem type and \-sfnvo options have same meaning like -standard mount options. +where the is filesystem type and \-sfnvo options have same meaning like +standard mount options. The \-t option is used for filesystems with subtypes +support (for example /sbin/mount.fuse -t fuse.sshfs). .SH FILES .TP 18n diff --git a/mount/umount.8 b/mount/umount.8 index 5ef861aa..fac88785 100644 --- a/mount/umount.8 +++ b/mount/umount.8 @@ -147,9 +147,13 @@ The syntax of external umount helpers is: .BI /sbin/umount. .RI { dir | device } .RB [ \-nlfvr ] +.RB [ \-t +.IR type.subtype ] .br where the is filesystem type or a value from "uhelper=" mtab option. +The \-t option is used for filesystems with subtypes support (for example +/sbin/mount.fuse -t fuse.sshfs). The uhelper (unprivileged umount helper) is possible to used when non-root user wants to umount a mountpoint which is not defined in the /etc/fstab file (e.g -- cgit v1.2.3 From 8f83100949e685ee0be3de39f3e6fd9b3805e683 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Sat, 28 Aug 2010 00:50:24 +0200 Subject: blockdev: fix typo in blockdev.8 Reported-by: Marcos Felipe Rasia de Mello Signed-off-by: Karel Zak --- disk-utils/blockdev.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk-utils/blockdev.8 b/disk-utils/blockdev.8 index c3d5dfd7..7176ffac 100644 --- a/disk-utils/blockdev.8 +++ b/disk-utils/blockdev.8 @@ -78,7 +78,7 @@ Set read-only. .IP "\fB\-\-setrw\fP" Set read-write. .SH AUTHOR -blockdev was written by Andries E. Brouwer and rewrittent by Karel Zak. +blockdev was written by Andries E. Brouwer and rewritten by Karel Zak. .SH AVAILABILITY The blockdev command is part of the util-linux-ng package and is available from ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/. -- cgit v1.2.3 From e31597d8eda23e17fcfd46959d72765b966bb405 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 30 Aug 2010 10:48:52 +0200 Subject: mount: add note about subtypes to fstab.5 Signed-off-by: Karel Zak --- mount/fstab.5 | 8 ++++++++ mount/mount.8 | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/mount/fstab.5 b/mount/fstab.5 index 1c5cdca9..8a834873 100644 --- a/mount/fstab.5 +++ b/mount/fstab.5 @@ -146,6 +146,14 @@ An entry .I none is useful for bind or move mounts. +.BR mount (8) +and +.BR umount (8) +support filesystem subtypes. The subtype is defined by '.subtype' suffix. For +example 'fuse.sshfs'. It's recommended to use subtype notation rather than add +any prefix to the first fstab field (for example 'sshfs#example.com' is +depreacated). + The fourth field, .RI ( fs_mntops ), describes the mount options associated with the filesystem. diff --git a/mount/mount.8 b/mount/mount.8 index 2fe0db8d..0147e71d 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -596,6 +596,15 @@ was known as Note, the real list of all supported filesystems depends on your kernel. +The programs +.B mount +and +.B umount +support filesystem subtypes. The subtype is defined by '.subtype' suffix. For +example 'fuse.sshfs'. It's recommended to use subtype notation rather than add +any prefix to the mount source (for example 'sshfs#example.com' is +depreacated). + For most types all the .B mount program has to do is issue a simple -- cgit v1.2.3 From abe3d704b6aeb6b82ff32e8599edb56525cdfd72 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 30 Aug 2010 11:43:41 +0200 Subject: mount: clean up fstab.5 Signed-off-by: Karel Zak --- mount/fstab.5 | 99 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/mount/fstab.5 b/mount/fstab.5 index 8a834873..c10490a4 100644 --- a/mount/fstab.5 +++ b/mount/fstab.5 @@ -40,11 +40,11 @@ .\" Tue Jun 15 20:02:18 1999: added LABEL and UUID .\" Sat Jul 14 2001: Michael K. Johnson added -O .\" -.TH FSTAB 5 "15 June 1999" "Linux 2.2" "Linux Programmer's Manual" +.TH FSTAB 5 "August 2010" "Linux 2.6" "Linux Programmer's Manual" .SH NAME fstab \- static information about the filesystems .SH SYNOPSIS -.B #include +.B /etc/fstab .SH DESCRIPTION The file .B fstab @@ -64,9 +64,10 @@ sequentially iterate through .B fstab doing their thing. -The first field, -.RI ( fs_spec ), -describes the block special device or +.B The first field +.RI ( fs_spec ). +.RS +This field describes the block special device or remote filesystem to be mounted. .LP For ordinary mounts it will hold (a link to) a block special @@ -86,16 +87,20 @@ writing LABEL=