diff --git a/configure.ac b/configure.ac index d3b298c..9da5b24 100644 --- a/configure.ac +++ b/configure.ac @@ -387,6 +387,8 @@ AC_CACHE_VAL([scanf_cv_alloc_modifier], [scanf_cv_alloc_modifier=as], [scanf_cv_alloc_modifier=no] ) + , + [scanf_cv_alloc_modifier=no] ) ) @@ -833,6 +835,8 @@ AC_ARG_ENABLE([ddate], ) UL_BUILD_INIT([ddate]) AM_CONDITIONAL(BUILD_DDATE, test "x$build_ddate" = xyes) +ruman1dir='${mandir}/ru/man1' +AC_SUBST([ruman1dir]) AC_ARG_ENABLE([agetty], diff --git a/fdisk/fdiskbsdlabel.h b/fdisk/fdiskbsdlabel.h index 9f9e091..e58e2ff 100644 --- a/fdisk/fdiskbsdlabel.h +++ b/fdisk/fdiskbsdlabel.h @@ -46,7 +46,7 @@ #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec" -#if defined (i386) || defined (__sparc__) || defined (__arm__) || \ +#if defined (__i386__) || defined (__sparc__) || defined (__arm__) || \ defined (__mips__) || defined (__s390__) || defined (__sh__) || \ defined(__x86_64__) || defined (__avr32__) || defined(__cris__) #define BSD_LABELSECTOR 1 diff --git a/include/list.h b/include/list.h index 3ce46ca..d8c3bf0 100644 --- a/include/list.h +++ b/include/list.h @@ -166,6 +166,10 @@ _INLINE_ void list_splice(struct list_head *list, struct list_head *head) #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +#define list_first_entry(head, type, member) \ + ((head) && (head)->next != (head) ? list_entry((head)->next, type, member) : NULL) + /** * list_for_each - iterate over elements in a list * @pos: the &struct list_head to use as a loop counter. diff --git a/lib/canonicalize.c b/lib/canonicalize.c index ab32c10..fd18af4 100644 --- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -174,9 +174,16 @@ canonicalize_path(const char *path) if (path == NULL) return NULL; - if (!myrealpath(path, canonical, PATH_MAX+1)) - return strdup(path); - + if (!myrealpath(path, canonical, PATH_MAX+1)) { + char *res = strdup(path); + if (res) { + p = strrchr(res, '/'); + /* delete trailing slash */ + if (p && p > res && *(p + 1) == '\0') + *p = '\0'; + } + return res; + } p = strrchr(canonical, '/'); if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 763f75c..6bd69d3 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -388,6 +388,7 @@ void blkid_reset_probe(blkid_probe pr) return; blkid_probe_reset_vals(pr); + blkid_probe_set_wiper(pr, 0, 0); pr->cur_chain = NULL; @@ -989,7 +990,7 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) len = sizeof(buf); DBG(DEBUG_LOWPROBE, printf( - "wiping [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n", + "do_wipe [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n", offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not")); l = lseek(fd, offset, SEEK_SET); @@ -1008,10 +1009,23 @@ int blkid_do_wipe(blkid_probe pr, int dryrun) if (chn->idx >= 0) { chn->idx--; DBG(DEBUG_LOWPROBE, - printf("wipe: moving %s chain index to %d\n", + printf("do_wipe: moving %s chain index to %d\n", chn->driver->name, chn->idx)); } + if (chn->idx == -1) { + /* blkid_do_probe() goes to the next chain if the index + * of the current chain is -1, so we have to set the + * chain pointer to the previos chain. + */ + size_t idx = chn->driver->id > 0 ? + chn->driver->id - 1 : 0; + + if (idx > 0) + pr->cur_chain = &pr->chains[idx]; + else if (idx == 0) + pr->cur_chain = NULL; + } } return 0; } @@ -1579,8 +1593,9 @@ size_t blkid_rtrim_whitespace(unsigned char *str) * for later resolution to conflicts between superblocks. * * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of - * the device. If we found another signature (for example MBR) this wiped area - * then the signature has been added later and LVM superblock should be ignore. + * the device. If we found another signature (for example MBR) within the + * wiped area then the signature has been added later and LVM superblock + * should be ignore. * * Note that this heuristic is not 100% reliable, for example "pvcreate --zero * n" allows to keep the begin of the device unmodified. It's probably better @@ -1588,6 +1603,16 @@ size_t blkid_rtrim_whitespace(unsigned char *str) * than for conflicts between filesystem superblocks -- existence of unwanted * partition table is very unusual, because PT is pretty visible (parsed and * interpreted by kernel). + * + * Note that we usually expect only one signature on the device, it means that + * we have to remember only one wiped area from previously successfully + * detected signature. + * + * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM) + * blkid_probe_use_wiper() -- try to use area (e.g. MBR) + * + * Note that there is not relation between _wiper and blkid_to_wipe(). + * */ void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) { @@ -1638,12 +1663,17 @@ int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn, return 0; } +/* + * Try to use any area -- if the area has been previously wiped then the + * previous probing result should be ignored (reseted). + */ void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size) { struct blkid_chain *chn = NULL; if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) { - DBG(DEBUG_LOWPROBE, printf("wiped area detected -- ignore previous results\n")); + DBG(DEBUG_LOWPROBE, printf("previously wiped area modified " + " -- ignore previous results\n")); blkid_probe_set_wiper(pr, 0, 0); blkid_probe_chain_reset_vals(pr, chn); } diff --git a/libmount/src/context.c b/libmount/src/context.c index 1f30292..f97dd36 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -1165,6 +1165,10 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt) src = mnt_fs_get_source(cxt->fs); + if (!src && (cxt->mountflags & MS_PROPAGATION)) + /* mount --make-{shared,private,...} */ + return mnt_fs_set_source(cxt->fs, "none"); + /* ignore filesystems without source or filesystems * where the source is quasi-path (//foo/bar) */ @@ -1203,7 +1207,7 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt) if ((cxt->mountflags & (MS_BIND | MS_MOVE | MS_PROPAGATION)) || mnt_fs_is_pseudofs(cxt->fs)) { - DBG(CXT, mnt_debug_h(cxt, "PROPAGATION/pseudo FS source: %s", path)); + DBG(CXT, mnt_debug_h(cxt, "BIND/MOVE/pseudo FS source: %s", path)); return rc; } diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 8cbc25b..c56ffd4 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -369,7 +369,12 @@ static int exec_helper(struct libmnt_context *cxt) args[i++] = mnt_fs_get_srcpath(cxt->fs);/* 2 */ args[i++] = mnt_fs_get_target(cxt->fs); /* 3 */ - if (mnt_context_is_sloppy(cxt)) + /* + * TODO: remove the exception for "nfs", -s is documented + * for years should be usable everywhere. + */ + if (mnt_context_is_sloppy(cxt) && + type && startswith(type, "nfs")) args[i++] = "-s"; /* 4 */ if (mnt_context_is_fake(cxt)) args[i++] = "-f"; /* 5 */ @@ -446,9 +451,14 @@ static int do_mount(struct libmnt_context *cxt, const char *try_type) src = mnt_fs_get_srcpath(cxt->fs); target = mnt_fs_get_target(cxt->fs); - if (!src || !target) + if (!target) return -EINVAL; - + if (!src) { + /* unnecessary, should be already resolved in + * mnt_context_prepare_srcpath(), but for sure... */ + DBG(CXT, mnt_debug_h(cxt, "WARNING: source is NULL -- using \"none\"!")); + src = "none"; + } type = try_type ? : mnt_fs_get_fstype(cxt->fs); if (!(flags & MS_MGC_MSK)) diff --git a/libmount/src/fs.c b/libmount/src/fs.c index a28e66c..19650cb 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -304,11 +304,7 @@ int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source) assert(fs); - if (source && !strcmp(source, "none")) { - free(source); - source = NULL; - - } else if (source && strchr(source, '=')) { + if (source && strchr(source, '=')) { if (blkid_parse_tag_string(source, &t, &v) != 0) return -1; } @@ -341,6 +337,7 @@ int mnt_fs_set_source(struct libmnt_fs *fs, const char *source) if (!fs) return -EINVAL; + if (source) { p = strdup(source); if (!p) @@ -353,6 +350,41 @@ int mnt_fs_set_source(struct libmnt_fs *fs, const char *source) return rc; } +/* + * Compares @fs source path with @path. The tailing slash is ignored. + * See also mnt_fs_match_source(). + * + * Returns: 1 if @fs source path equal to @path, otherwise 0. + */ +int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path) +{ + const char *p; + + if (!fs) + return 0; + + p = mnt_fs_get_srcpath(fs); + + if (!mnt_fs_is_pseudofs(fs)) + return streq_except_trailing_slash(p, path); + + if (!p && !path) + return 1; + + return p && path && strcmp(p, path) == 0; +} + +/* + * Compares @fs target path with @path. The tailing slash is ignored. + * See also mnt_fs_match_target(). + * + * Returns: 1 if @fs target path equal to @path, otherwise 0. + */ +int mnt_fs_streq_target(struct libmnt_fs *fs, const char *path) +{ + return fs && streq_except_trailing_slash(mnt_fs_get_target(fs), path); +} + /** * mnt_fs_get_tag: * @fs: fs @@ -1114,7 +1146,7 @@ int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, return 0; /* 1) native paths */ - rc = !strcmp(target, fs->target); + rc = mnt_fs_streq_target(fs, target); if (!rc && cache) { /* 2) - canonicalized and non-canonicalized */ @@ -1146,10 +1178,6 @@ int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The * 2nd and 3rd attempts are not performed if @fs->source is tag. * - * Note that valid source path is NULL; the libmount uses NULL instead of - * "none". The "none" is used in /proc/{mounts,self/mountninfo} for pseudo - * filesystems. - * * Returns: 1 if @fs source is equal to @source else 0. */ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, @@ -1161,15 +1189,15 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, if (!fs) return 0; - /* undefined source -- "none" in /proc */ - if (source == NULL && fs->source == NULL) + /* 1) native paths... */ + if (mnt_fs_streq_srcpath(fs, source) == 1) return 1; - if (source == NULL || fs->source == NULL) + if (!source || !fs->source) return 0; - /* 1) native paths/tags */ - if (streq_except_trailing_slash(source, fs->source)) + /* ... and tags */ + if (fs->tagname && strcmp(source, fs->source) == 0) return 1; if (!cache) @@ -1183,7 +1211,7 @@ int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, /* 2) canonicalized and native */ src = mnt_fs_get_srcpath(fs); - if (src && streq_except_trailing_slash(cn, src)) + if (src && mnt_fs_streq_srcpath(fs, cn)) return 1; /* 3) canonicalized and canonicalized */ diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index fa0edf5..a7b5c0d 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -367,6 +367,11 @@ extern struct libmnt_fs *mnt_copy_mtab_fs(const struct libmnt_fs *fs); extern int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source); extern int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype); +/* exported in v2.22 */ +extern int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path); +extern int mnt_fs_streq_target(struct libmnt_fs *fs, const char *path); + + /* context.c */ extern int mnt_context_prepare_srcpath(struct libmnt_context *cxt); extern int mnt_context_prepare_target(struct libmnt_context *cxt); diff --git a/libmount/src/tab.c b/libmount/src/tab.c index 37f47bd..f3ec573 100644 --- a/libmount/src/tab.c +++ b/libmount/src/tab.c @@ -286,6 +286,11 @@ int mnt_table_next_child_fs(struct libmnt_table *tb, struct libmnt_iter *itr, id = mnt_fs_get_id(fs); + /* avoid infinite loop. This only happens in rare cases + * such as in early userspace when the rootfs is its own parent */ + if (id == parent_id) + continue; + if ((!lastchld_id || id > lastchld_id) && (!*chld || id < chld_id)) { *chld = fs; @@ -438,7 +443,7 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat /* native @target */ mnt_reset_iter(&itr, direction); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - if (fs->target && strcmp(fs->target, path) == 0) + if (mnt_fs_streq_target(fs, path)) return fs; } if (!tb->cache || !(cn = mnt_resolve_path(path, tb->cache))) @@ -447,7 +452,7 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat /* canonicalized paths in struct libmnt_table */ mnt_reset_iter(&itr, direction); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - if (fs->target && strcmp(fs->target, cn) == 0) + if (mnt_fs_streq_target(fs, cn)) return fs; } @@ -456,12 +461,13 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat while(mnt_table_next_fs(tb, &itr, &fs) == 0) { char *p; - if (!fs->target || !mnt_fs_is_swaparea(fs) || + if (!fs->target || mnt_fs_is_swaparea(fs) || (*fs->target == '/' && *(fs->target + 1) == '\0')) continue; p = mnt_resolve_path(fs->target, tb->cache); - if (strcmp(cn, p) == 0) + /* both canonicalized, strcmp() is fine here */ + if (p && strcmp(cn, p) == 0) return fs; } return NULL; @@ -480,9 +486,8 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat * The 2nd, 3rd and 4th iterations are not performed when @tb cache is not * set (see mnt_table_set_cache()). * - * Note that valid source path is NULL; the libmount uses NULL instead of - * "none". The "none" is used in /proc/{mounts,self/mountninfo} for pseudo - * filesystems. + * Note that NULL is a valid source path; it will be replaced with "none". The + * "none" is used in /proc/{mounts,self/mountinfo} for pseudo filesystems. * * Returns: a tab entry or NULL. */ @@ -501,16 +506,10 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa /* native paths */ mnt_reset_iter(&itr, direction); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - const char *src = mnt_fs_get_source(fs); - - p = mnt_fs_get_srcpath(fs); - - if (path == NULL && src == NULL) - return fs; /* source is "none" */ - if (path && p && streq_except_trailing_slash(p, path)) + if (mnt_fs_streq_srcpath(fs, path)) return fs; - if (!p && src) - ntags++; /* mnt_fs_get_srcpath() returs nothing, it's TAG */ + if (mnt_fs_get_tag(fs, NULL, NULL) == 0) + ntags++; } if (!path || !tb->cache || !(cn = mnt_resolve_path(path, tb->cache))) @@ -520,8 +519,7 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa if (ntags < mnt_table_get_nents(tb)) { mnt_reset_iter(&itr, direction); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - p = mnt_fs_get_srcpath(fs); - if (p && streq_except_trailing_slash(p, cn)) + if (mnt_fs_streq_srcpath(fs, cn)) return fs; } } @@ -552,7 +550,9 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa if (mnt_fs_get_tag(fs, &t, &v)) continue; x = mnt_resolve_tag(t, v, tb->cache); - if (x && streq_except_trailing_slash(x, cn)) + + /* both canonicalized, strcmp() is fine here */ + if (x && strcmp(x, cn) == 0) return fs; } } @@ -567,7 +567,9 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa p = mnt_fs_get_srcpath(fs); if (p) p = mnt_resolve_path(p, tb->cache); - if (p && streq_except_trailing_slash(cn, p)) + + /* both canonicalized, strcmp() is fine here */ + if (p && strcmp(p, cn) == 0) return fs; } } @@ -702,16 +704,18 @@ struct libmnt_fs *mnt_table_find_pair(struct libmnt_table *tb, const char *sourc } /* - * @tb: /proc/self/mountinfo - * @fs: filesystem - * @mountflags: MS_BIND or 0 - * @fsroot: fs-root that will be probably used in the mountinfo file + * tb: /proc/self/mountinfo + * fs: filesystem + * mountflags: MS_BIND or 0 + * fsroot: fs-root that will be probably used in the mountinfo file * for @fs after mount(2) * * For btrfs subvolumes this function returns NULL, but @fsroot properly set. * * Returns: entry from @tb that will be used as a source for @fs if the @fs is * bindmount. + * + * Don't export to library API! */ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, struct libmnt_fs *fs, @@ -814,6 +818,20 @@ err: return NULL; } +static int is_mountinfo(struct libmnt_table *tb) +{ + struct libmnt_fs *fs; + + if (!tb) + return 0; + + fs = list_first_entry(&tb->ents, struct libmnt_fs, ents); + if (fs && mnt_fs_is_kernel(fs) && mnt_fs_get_root(fs)) + return 1; + + return 0; +} + /** * mnt_table_is_mounted: * @tb: /proc/self/mountinfo file @@ -829,10 +847,9 @@ err: int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) { char *root = NULL; - struct libmnt_fs *src_fs; - const char *src, *tgt; - char *xsrc = NULL; - int flags = 0, rc = 0; + const char *src = NULL; + char *xsrc = NULL, *tgt; + int rc = 0; assert(tb); assert(fstab_fs); @@ -840,39 +857,49 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) if (mnt_fs_is_swaparea(fstab_fs)) return 0; - if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0) - flags = MS_BIND; + if (is_mountinfo(tb)) { + /* @tb is mountinfo, so we can try to use fs-roots */ + struct libmnt_fs *fs; + int flags = 0; + + if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0) + flags = MS_BIND; - src_fs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root); - if (src_fs) - src = mnt_fs_get_srcpath(src_fs); + fs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root); + if (fs) + src = mnt_fs_get_srcpath(fs); + } + + if (src) + src = xsrc = mnt_resolve_spec(src, tb->cache); else if (mnt_fs_is_pseudofs(fstab_fs)) src = mnt_fs_get_source(fstab_fs); else src = xsrc = mnt_resolve_spec(mnt_fs_get_source(fstab_fs), tb->cache); - tgt = mnt_fs_get_target(fstab_fs); + tgt = mnt_resolve_path(mnt_fs_get_target(fstab_fs), tb->cache); - if (tgt && src && root) { + if (tgt && src) { struct libmnt_iter itr; struct libmnt_fs *fs; mnt_reset_iter(&itr, MNT_ITER_FORWARD); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - const char *s = mnt_fs_get_srcpath(fs), - *t = mnt_fs_get_target(fs), - *r = mnt_fs_get_root(fs); - - /* - * Note that kernel can add tailing slash to the - * network filesystem source paths. - */ - if (t && s && r && - strcmp(t, tgt) == 0 && - streq_except_trailing_slash(s, src) && - strcmp(r, root) == 0) + + if (root) { + /* mountinfo: compare root, source and target */ + const char *r = mnt_fs_get_root(fs); + + if (r && strcmp(r, root) == 0 && + mnt_fs_streq_srcpath(fs, src) && + mnt_fs_streq_target(fs, tgt)) + break; + } + /* mtab: compare source and target */ + else if (mnt_fs_streq_srcpath(fs, src) && + mnt_fs_streq_target(fs, tgt)) break; } if (fs) @@ -881,6 +908,8 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) if (xsrc && !tb->cache) free(xsrc); + if (!tb->cache) + free(tgt); free(root); return rc; diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c index 0f618bb..28c8536 100644 --- a/libmount/src/tab_parse.c +++ b/libmount/src/tab_parse.c @@ -180,12 +180,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, char *s) unmangle_string(fs->vfs_optstr); unmangle_string(fstype); unmangle_string(src); - - if (!strcmp(fs->fs_optstr, "none")) { - free(fs->fs_optstr); - fs->fs_optstr = NULL; - } else - unmangle_string(fs->fs_optstr); + unmangle_string(fs->fs_optstr); rc = __mnt_fs_set_fstype_ptr(fs, fstype); if (!rc) { @@ -733,21 +728,14 @@ static struct libmnt_fs *mnt_table_merge_user_fs(struct libmnt_table *tb, struct mnt_reset_iter(&itr, MNT_ITER_BACKWARD); while(mnt_table_next_fs(tb, &itr, &fs) == 0) { - const char *s = mnt_fs_get_srcpath(fs), - *t = mnt_fs_get_target(fs), - *r = mnt_fs_get_root(fs); + const char *r = mnt_fs_get_root(fs); if (fs->flags & MNT_FS_MERGED) continue; - /* - * Note that kernel can add tailing slash to the network - * filesystem source path - */ - if (s && t && r && - strcmp(t, target) == 0 && - streq_except_trailing_slash(s, src) && - strcmp(r, root) == 0) + if (r && strcmp(r, root) == 0 + && mnt_fs_streq_target(fs, target) + && mnt_fs_streq_srcpath(fs, src)) break; } diff --git a/libmount/src/utils.c b/libmount/src/utils.c index c7a1fd1..4d316d1 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -235,6 +235,7 @@ int mnt_fstype_is_pseudofs(const char *type) strcmp(type, "binfmt_misc") == 0 || strcmp(type, "fuse.gvfs-fuse-daemon") == 0 || strcmp(type, "debugfs") == 0 || + strcmp(type, "nfsd") == 0 || strcmp(type, "spufs") == 0) return 1; return 0; diff --git a/login-utils/login.c b/login-utils/login.c index 84d8b1b..4f448f8 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -128,6 +128,22 @@ static int timeout = LOGIN_TIMEOUT; static int child_pid = 0; static volatile int got_sig = 0; +#ifdef LOGIN_CHOWN_VCS +/* true if the filedescriptor fd is a console tty, very Linux specific */ +static int is_consoletty(int fd) +{ + struct stat stb; + + if ((fstat(fd, &stb) >= 0) + && (major(stb.st_rdev) == TTY_MAJOR) + && (minor(stb.st_rdev) < 64)) { + return 1; + } + return 0; +} +#endif + + /* * Robert Ambrose writes: * A couple of my users have a problem with login processes hanging around @@ -316,15 +332,15 @@ static void chown_tty(struct login_context *cxt) #ifdef LOGIN_CHOWN_VCS if (is_consoletty(0)) { - if (chown(cxt->vcs, uid, gid)) /* vcs */ - chown_err(cxt->vcs, uid, gid); - if (chmod(cxt->vcs, cxt->tty_mode)) - chmod_err(cxt->vcs, cxt->tty_mode); - - if (chown(cxt->vcsa, uid, gid)) /* vcsa */ - chown_err(cxt->vcsa, uid, gid); - if (chmod(cxt->vcsa, cxt->tty_mode)) - chmod_err(cxt->vcsa, cxt->tty_mode); + if (chown(cxt->vcsn, uid, gid)) /* vcs */ + chown_err(cxt->vcsn, uid, gid); + if (chmod(cxt->vcsn, cxt->tty_mode)) + chmod_err(cxt->vcsn, cxt->tty_mode); + + if (chown(cxt->vcsan, uid, gid)) /* vcsa */ + chown_err(cxt->vcsan, uid, gid); + if (chmod(cxt->vcsan, cxt->tty_mode)) + chmod_err(cxt->vcsan, cxt->tty_mode); } #endif } @@ -403,21 +419,6 @@ static void init_tty(struct login_context *cxt) } -#ifdef LOGIN_CHOWN_VCS -/* true if the filedescriptor fd is a console tty, very Linux specific */ -static int is_consoletty(int fd) -{ - struct stat stb; - - if ((fstat(fd, &stb) >= 0) - && (major(stb.st_rdev) == TTY_MAJOR) - && (minor(stb.st_rdev) < 64)) { - return 1; - } - return 0; -} -#endif - /* * Log failed login attempts in _PATH_BTMP if that exists. * Must be called only with username the name of an actual user. @@ -1145,13 +1146,10 @@ static void init_environ(struct login_context *cxt) setenv("TERM", termenv, 1); if (pwd->pw_uid) - setenv("PATH", getlogindefs_str("ENV_PATH", _PATH_DEFPATH), 1); - else { - const char *x = getlogindefs_str("ENV_ROOTPATH", NULL); - if (!x) - x = getlogindefs_str("ENV_SUPATH", _PATH_DEFPATH_ROOT); - setenv("PATH", x, 1); - } + logindefs_setenv("PATH", "ENV_PATH", _PATH_DEFPATH); + + else if (logindefs_setenv("PATH", "ENV_ROOTPATH", NULL) != 0) + logindefs_setenv("PATH", "ENV_SUPATH", _PATH_DEFPATH_ROOT); /* mailx will give a funny error msg if you forget this one */ len = snprintf(tmp, sizeof(tmp), "%s/%s", _PATH_MAILDIR, pwd->pw_name); diff --git a/login-utils/logindefs.c b/login-utils/logindefs.c index fe590e9..e9517ac 100644 --- a/login-utils/logindefs.c +++ b/login-utils/logindefs.c @@ -211,6 +211,43 @@ const char *getlogindefs_str(const char *name, const char *dflt) return ptr->value; } +/* + * For compatibililty with shadow-utils we have tu support additional + * syntax for environment variables in login.defs(5) file. The standard + * syntax is: + * + * ENV_FOO data + * + * but shadow-utils supports also + * + * ENV_FOO FOO=data + * + * the FOO= prefix has to be remove before we call setenv(). + */ +int logindefs_setenv(const char *name, const char *conf, const char *dflt) +{ + const char *val = getlogindefs_str(conf, dflt); + const char *p; + + if (!val) + return -1; + + p = strchr(val, '='); + if (p) { + size_t sz = strlen(name); + + if (strncmp(val, name, sz) == 0 && *(p + 1)) { + val = p + 1; + if (*val == '"') + val++; + if (!*val) + val = dflt; + } + } + + return val ? setenv(name, val, 1) : -1; +} + #ifdef TEST_PROGRAM int main(int argc, char *argv[]) { diff --git a/login-utils/logindefs.h b/login-utils/logindefs.h index 37d19e1..163869d 100644 --- a/login-utils/logindefs.h +++ b/login-utils/logindefs.h @@ -5,5 +5,6 @@ extern int getlogindefs_bool(const char *name, int dflt); extern long getlogindefs_num(const char *name, long dflt); extern const char *getlogindefs_str(const char *name, const char *dflt); extern void free_getlogindefs_data(void); +extern int logindefs_setenv(const char *name, const char *conf, const char *dflt); #endif /* UTIL_LINUX_LOGINDEFS_H */ diff --git a/man/ru/Makefile.am b/man/ru/Makefile.am index 799feca..281ec23 100644 --- a/man/ru/Makefile.am +++ b/man/ru/Makefile.am @@ -1,9 +1,6 @@ include $(top_srcdir)/config/include-Makefile.am -mandir = @mandir@/ru - -dist_man_MANS = - if BUILD_DDATE -dist_man_MANS += ddate.1 +ruman1_DATA = ddate.1 +EXTRA_DIST = $(ruman1_DATA) endif diff --git a/misc-utils/lsblk.8 b/misc-utils/lsblk.8 index 028b19f..286d54b 100644 --- a/misc-utils/lsblk.8 +++ b/misc-utils/lsblk.8 @@ -59,7 +59,7 @@ Use key="value" output format. Use the raw output format. .IP "\fB\-t, \-\-topology\fP" Output info about block device topology. -This option is equivalent to "-o NAME,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-SEC,ROTA,SCHED". +This option is equivalent to "-o NAME,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-SEC,ROTA,SCHED,RQ-SIZE". .SH NOTES For the partitions are some information (e.g. queue attributes) inherited from parental device. diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index 8468b3f..54bf360 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -478,9 +478,14 @@ static void set_tt_data(struct blkdev_cxt *cxt, int col, int id, struct tt_line switch(id) { case COL_NAME: if (cxt->dm_name) { - snprintf(buf, sizeof(buf), "%s (%s)", + if ((lsblk->tt->flags & TT_FL_RAW) || + (lsblk->tt->flags & TT_FL_EXPORT)) + tt_line_set_data(ln, col, xstrdup(cxt->dm_name)); + else { + snprintf(buf, sizeof(buf), "%s (%s)", cxt->dm_name, cxt->name); - tt_line_set_data(ln, col, xstrdup(buf)); + tt_line_set_data(ln, col, xstrdup(buf)); + } break; } case COL_KNAME: diff --git a/mount/fstab.5 b/mount/fstab.5 index b0cd763..c618947 100644 --- a/mount/fstab.5 +++ b/mount/fstab.5 @@ -167,7 +167,7 @@ support filesystem 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). +deprecated). .RE .B The fourth field diff --git a/sys-utils/losetup.8 b/sys-utils/losetup.8 index a68836e..f50b072 100644 --- a/sys-utils/losetup.8 +++ b/sys-utils/losetup.8 @@ -80,6 +80,8 @@ for non-root users. force loop driver to reread size of the file associated with the specified loop device .IP "\fB\-d, \-\-detach\fP \fIloopdev\fP..." detach the file or device associated with the specified loop device(s) +.IP "\fB\-D, \-\-detach-all\fP" +detach all associated loop devices .IP "\fB\-e, \-E, \-\-encryption \fIencryption_type\fP" enable data encryption with specified name or number .IP "\fB\-f, \-\-find\fP" diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c index 16ace6f..9f03151 100644 --- a/sys-utils/losetup.c +++ b/sys-utils/losetup.c @@ -362,7 +362,7 @@ int main(int argc, char **argv) if (flags & LOOPDEV_FL_OFFSET) loopcxt_set_offset(&lc, offset); if (flags & LOOPDEV_FL_SIZELIMIT) - loopcxt_set_offset(&lc, sizelimit); + loopcxt_set_sizelimit(&lc, sizelimit); if (lo_flags) loopcxt_set_flags(&lc, lo_flags); if ((res = loopcxt_set_backing_file(&lc, file))) { diff --git a/sys-utils/mount.8 b/sys-utils/mount.8 index 78e7a41..44d4402 100644 --- a/sys-utils/mount.8 +++ b/sys-utils/mount.8 @@ -2760,6 +2760,10 @@ mount failure .TP .BR 64 some mount succeeded +.RE + +The command mount -a returns 0 (all success), 32 (all failed) or 64 (some +failed, some success). .SH NOTES The syntax of external mount helpers is: diff --git a/sys-utils/mount.c b/sys-utils/mount.c index 15510e0..12ec372 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -182,6 +182,8 @@ static int mount_all(struct libmnt_context *cxt) struct libmnt_fs *fs; int mntrc, ignored, rc = MOUNT_EX_SUCCESS; + int nsucc = 0, nerrs = 0; + itr = mnt_new_iter(MNT_ITER_FORWARD); if (!itr) { warn(_("failed to initialize libmount iterator")); @@ -197,31 +199,40 @@ static int mount_all(struct libmnt_context *cxt) printf(ignored == 1 ? _("%-25s: ignored\n") : _("%-25s: already mounted\n"), tgt); - } else if (mnt_context_is_fork(cxt)) { if (mnt_context_is_verbose(cxt)) printf("%-25s: mount successfully forked\n", tgt); } else { - rc |= mk_exit_code(cxt, mntrc); + mk_exit_code(cxt, mntrc); /* to print warnings */ if (mnt_context_get_status(cxt)) { - rc |= MOUNT_EX_SOMEOK; + nsucc++; if (mnt_context_is_verbose(cxt)) printf("%-25s: successfully mounted\n", tgt); - } + } else + nerrs++; } } if (mnt_context_is_parent(cxt)) { /* wait for mount --fork children */ - int nerrs = 0, nchildren = 0; + int nchildren = 0; + + nerrs = 0, nsucc = 0; rc = mnt_context_wait_for_children(cxt, &nchildren, &nerrs); if (!rc && nchildren) - rc = nchildren == nerrs ? MOUNT_EX_FAIL : MOUNT_EX_SOMEOK; + nsucc = nchildren - nerrs; } + if (nerrs == 0) + rc = MOUNT_EX_SUCCESS; /* all success */ + else if (nsucc == 0) + rc = MOUNT_EX_FAIL; /* all failed */ + else + rc = MOUNT_EX_SOMEOK; /* some success, some failed */ + mnt_free_iter(itr); return rc; } @@ -290,6 +301,25 @@ static void selinux_warning(struct libmnt_context *cxt, const char *tgt) # define selinux_warning(_x, _y) #endif +/* temporary in mount(8) for v2.21.x releases, in v2.22 will be in libmount + */ +static int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path) +{ + const char *p; + + if (!fs) + return 0; + + p = mnt_fs_get_srcpath(fs); + + if (!mnt_fs_is_pseudofs(fs)) + return streq_except_trailing_slash(p, path); + + if (!p && !path) + return 1; + + return p && path && strcmp(p, path) == 0; +} /* * rc = 0 success @@ -336,7 +366,11 @@ try_readonly: return MOUNT_EX_USAGE; } - if (src == NULL || tgt == NULL) { + /* + * TODO: add mnt_context_fstab_applied() to check if we found + * target/source in the file. + */ + if (!tgt) { if (mflags & MS_REMOUNT) warnx(_("%s not mounted"), src ? src : tgt); else @@ -408,7 +442,7 @@ try_readonly: const char *s = mnt_fs_get_srcpath(fs), *t = mnt_fs_get_target(fs); - if (t && s && streq_except_trailing_slash(s, src)) + if (t && s && mnt_fs_streq_srcpath(fs, src)) fprintf(stderr, _( " %s is already mounted on %s\n"), s, t); } @@ -697,7 +731,7 @@ int main(int argc, char **argv) longopts, NULL)) != -1) { /* only few options are allowed for non-root users */ - if (mnt_context_is_restricted(cxt) && !strchr("hlLUVvpr", c)) + if (mnt_context_is_restricted(cxt) && !strchr("hlLUVvpri", c)) exit_non_root(option_to_longopt(c, longopts)); switch(c) { diff --git a/sys-utils/mountpoint.c b/sys-utils/mountpoint.c index 5cc833d..d0a0069 100644 --- a/sys-utils/mountpoint.c +++ b/sys-utils/mountpoint.c @@ -40,12 +40,12 @@ static int quiet; -static dev_t dir_to_device(const char *spec) +static int dir_to_device(const char *spec, dev_t *dev) { struct libmnt_table *tb = mnt_new_table_from_file("/proc/self/mountinfo"); struct libmnt_fs *fs; struct libmnt_cache *cache; - dev_t res = 0; + int rc = -1; if (!tb) { /* @@ -57,7 +57,7 @@ static dev_t dir_to_device(const char *spec) int len; if (stat(spec, &st) != 0) - return 0; + return -1; cn = mnt_resolve_path(spec, NULL); /* canonicalize */ @@ -65,15 +65,17 @@ static dev_t dir_to_device(const char *spec) free(cn); if (len < 0 || (size_t) len + 1 > sizeof(buf)) - return 0; + return -1; if (stat(buf, &pst) !=0) - return 0; + return -1; if ((st.st_dev != pst.st_dev) || - (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) - return st.st_dev; + (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) { + *dev = st.st_dev; + return 0; + } - return 0; + return -1; } /* to canonicalize all necessary paths */ @@ -81,12 +83,14 @@ static dev_t dir_to_device(const char *spec) mnt_table_set_cache(tb, cache); fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD); - if (fs && mnt_fs_get_target(fs)) - res = mnt_fs_get_devno(fs); + if (fs && mnt_fs_get_target(fs)) { + *dev = mnt_fs_get_devno(fs); + rc = 0; + } mnt_free_table(tb); mnt_free_cache(cache); - return res; + return rc; } static int print_devno(const char *devname, struct stat *st) @@ -185,8 +189,8 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("%s: not a directory"), spec); return EXIT_FAILURE; } - src = dir_to_device(spec); - if (!src) { + + if ( dir_to_device(spec, &src)) { if (!quiet) printf(_("%s is not a mountpoint\n"), spec); return EXIT_FAILURE; diff --git a/term-utils/script.c b/term-utils/script.c index 58f9790..0d891b8 100644 --- a/term-utils/script.c +++ b/term-utils/script.c @@ -437,6 +437,16 @@ doshell(void) { else shname = shell; + /* + * When invoked from within /etc/csh.login, script spawns a csh shell + * that spawns programs that cannot be killed with a SIGTERM. This is + * because csh has a documented behaviour wherein it disables all + * signals when processing the /etc/csh.* files. + * + * Let's restore the default behavior. + */ + signal(SIGTERM, SIG_DFL); + if (cflg) execl(shell, shname, "-c", cflg, NULL); else diff --git a/tests/Makefile.am b/tests/Makefile.am index fd62519..2c72318 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,5 +7,5 @@ EXTRA_DIST = expected \ functions.sh \ run.sh -distclean-local: +clean-local: rm -rf output diff diff --git a/tests/expected/libmount/tabfiles-find-target2 b/tests/expected/libmount/tabfiles-find-target2 new file mode 100644 index 0000000..8a6c57b --- /dev/null +++ b/tests/expected/libmount/tabfiles-find-target2 @@ -0,0 +1,5 @@ +------ fs: +source: /dev/foo +target: /any/foo/ +fstype: auto +optstr: defaults diff --git a/tests/expected/libmount/tabfiles-find-target3 b/tests/expected/libmount/tabfiles-find-target3 new file mode 100644 index 0000000..8a6c57b --- /dev/null +++ b/tests/expected/libmount/tabfiles-find-target3 @@ -0,0 +1,5 @@ +------ fs: +source: /dev/foo +target: /any/foo/ +fstype: auto +optstr: defaults diff --git a/tests/expected/libmount/tabfiles-parse-fstab b/tests/expected/libmount/tabfiles-parse-fstab index 14bdfb4..d661526 100644 --- a/tests/expected/libmount/tabfiles-parse-fstab +++ b/tests/expected/libmount/tabfiles-parse-fstab @@ -58,3 +58,8 @@ target: /mnt/gogogo fstype: cifs optstr: user=SRGROUP/baby,noauto user-optstr: user=SRGROUP/baby,noauto +------ fs: +source: /dev/foo +target: /any/foo/ +fstype: auto +optstr: defaults diff --git a/tests/expected/libmount/tabfiles-parse-mountinfo b/tests/expected/libmount/tabfiles-parse-mountinfo index 95182dd..4470801 100644 --- a/tests/expected/libmount/tabfiles-parse-mountinfo +++ b/tests/expected/libmount/tabfiles-parse-mountinfo @@ -296,7 +296,7 @@ id: 41 parent: 20 devno: 253:0 ------ fs: -source: (null) +source: none target: /proc/sys/fs/binfmt_misc fstype: binfmt_misc optstr: rw,relatime diff --git a/tests/expected/libmount/tabfiles-parse-mtab b/tests/expected/libmount/tabfiles-parse-mtab index d7171ea..ffd0c13 100644 --- a/tests/expected/libmount/tabfiles-parse-mtab +++ b/tests/expected/libmount/tabfiles-parse-mtab @@ -42,7 +42,7 @@ fstype: ext4 optstr: rw,noatime VFS-optstr: rw,noatime ------ fs: -source: (null) +source: none target: /proc/sys/fs/binfmt_misc fstype: binfmt_misc optstr: rw diff --git a/tests/expected/libmount/update-utab-mount b/tests/expected/libmount/update-utab-mount index 1784e00..58a0179 100644 --- a/tests/expected/libmount/update-utab-mount +++ b/tests/expected/libmount/update-utab-mount @@ -1,3 +1,3 @@ SRC=/dev/sdb1 TARGET=/mnt/bar ROOT=/ OPTS=user SRC=/dev/sda2 TARGET=/mnt/xyz ROOT=/ OPTS=loop=/dev/loop0,uhelper=hal -TARGET=/proc ROOT=/ OPTS=user +SRC=none TARGET=/proc ROOT=/ OPTS=user diff --git a/tests/expected/libmount/update-utab-move b/tests/expected/libmount/update-utab-move index 12917cc..6008140 100644 --- a/tests/expected/libmount/update-utab-move +++ b/tests/expected/libmount/update-utab-move @@ -1,3 +1,3 @@ SRC=/dev/sdb1 TARGET=/mnt/newbar ROOT=/ OPTS=user SRC=/dev/sda2 TARGET=/mnt/newxyz ROOT=/ OPTS=loop=/dev/loop0,uhelper=hal -TARGET=/proc ROOT=/ OPTS=user +SRC=none TARGET=/proc ROOT=/ OPTS=user diff --git a/tests/expected/libmount/update-utab-remount b/tests/expected/libmount/update-utab-remount index 737e2a3..8e344b3 100644 --- a/tests/expected/libmount/update-utab-remount +++ b/tests/expected/libmount/update-utab-remount @@ -1,3 +1,3 @@ SRC=/dev/sdb1 TARGET=/mnt/newbar ROOT=/ OPTS=user SRC=/dev/sda2 TARGET=/mnt/newxyz ROOT=/ OPTS=user -TARGET=/proc ROOT=/ OPTS=user +SRC=none TARGET=/proc ROOT=/ OPTS=user diff --git a/tests/expected/mount/fstab-none b/tests/expected/mount/fstab-none new file mode 100644 index 0000000..3582111 --- /dev/null +++ b/tests/expected/mount/fstab-none @@ -0,0 +1 @@ +Success diff --git a/tests/expected/mount/shared-subtree b/tests/expected/mount/shared-subtree new file mode 100644 index 0000000..3582111 --- /dev/null +++ b/tests/expected/mount/shared-subtree @@ -0,0 +1 @@ +Success diff --git a/tests/expected/mount/shared-subtree-make-private b/tests/expected/mount/shared-subtree-make-private new file mode 100644 index 0000000..39cdd0d --- /dev/null +++ b/tests/expected/mount/shared-subtree-make-private @@ -0,0 +1 @@ +- diff --git a/tests/expected/mount/shared-subtree-make-shared b/tests/expected/mount/shared-subtree-make-shared new file mode 100644 index 0000000..8a205e8 --- /dev/null +++ b/tests/expected/mount/shared-subtree-make-shared @@ -0,0 +1 @@ +shared diff --git a/tests/expected/mount/shared-subtree-make-unbindable b/tests/expected/mount/shared-subtree-make-unbindable new file mode 100644 index 0000000..376cfac --- /dev/null +++ b/tests/expected/mount/shared-subtree-make-unbindable @@ -0,0 +1 @@ +unbindable diff --git a/tests/functions.sh b/tests/functions.sh index 85b1621..6556e4e 100644 --- a/tests/functions.sh +++ b/tests/functions.sh @@ -93,6 +93,8 @@ function ts_init_core_subtest_env { TS_MOUNTPOINT="$TS_OUTDIR/${TS_TESTNAME}-${TS_SUBNAME}-mnt" rm -f $TS_OUTPUT $TS_VGDUMP + [ -d "$TS_OUTDIR" ] || mkdir -p "$TS_OUTDIR" + touch $TS_OUTPUT [ -n "$TS_VALGRIND_CMD" ] && touch $TS_VGDUMP } @@ -127,8 +129,6 @@ function ts_init_env { BLKID_FILE="$TS_OUTDIR/${TS_TESTNAME}.blkidtab" - [ -d "$TS_OUTDIR" ] || mkdir -p "$TS_OUTDIR" - [ -d "$TS_DIFFDIR" ] || mkdir -p "$TS_DIFFDIR" declare -a TS_SUID_PROGS declare -a TS_SUID_USER @@ -141,6 +141,8 @@ function ts_init_env { export BLKID_FILE rm -f $TS_OUTPUT $TS_VGDUMP + [ -d "$TS_OUTDIR" ] || mkdir -p "$TS_OUTDIR" + touch $TS_OUTPUT [ -n "$TS_VALGRIND_CMD" ] && touch $TS_VGDUMP @@ -219,8 +221,15 @@ function ts_gen_diff { local res=0 if [ -s "$TS_OUTPUT" ]; then + + [ -d "$TS_DIFFDIR" ] || mkdir -p "$TS_DIFFDIR" diff -u $TS_EXPECTED $TS_OUTPUT > $TS_DIFF - [ -s $TS_DIFF ] && res=1 + + if [ -s $TS_DIFF ]; then + res=1 + else + rm -f $TS_DIFF; + fi else res=1 fi diff --git a/tests/ts/build-sys/config b/tests/ts/build-sys/config index 7ede38c..e2c2b00 100755 --- a/tests/ts/build-sys/config +++ b/tests/ts/build-sys/config @@ -52,9 +52,18 @@ for conf in $config_gen_dir/config-gen.d/*.conf; do esac fi done + + # clean the tree, but exclude tests/{diff,output} dirs + # + [ -d tests/diff ] && mv tests/diff tests/diff.save + [ -d tests/output ] && mv tests/output tests/output.save + make -j clean &> /dev/null - cd $olddir + [ -d tests/diff.save ] && mv tests/diff.save tests/diff + [ -d tests/output.save ] && mv tests/output.save tests/output + + cd $olddir ts_finalize_subtest done diff --git a/tests/ts/libmount/context-utab b/tests/ts/libmount/context-utab index aa49806..4c1d117 100755 --- a/tests/ts/libmount/context-utab +++ b/tests/ts/libmount/context-utab @@ -67,6 +67,8 @@ grep -q $DEVICE /proc/mounts || \ echo "(by device) cannot find $DEVICE in /proc/mounts" >> $TS_OUTPUT 2>&1 ts_finalize_subtest +sleep 1 + ts_init_subtest "umount-by-devname" ts_valgrind $TESTPROG --umount $DEVICE >> $TS_OUTPUT 2>&1 grep -q $DEVICE /proc/mounts && @@ -81,6 +83,8 @@ grep -q $DEVICE $LIBMOUNT_UTAB || \ echo "(by label) cannot find $DEVICE in $LIBMOUNT_UTAB" >> $TS_OUTPUT 2>&1 ts_finalize_subtest +sleep 1 + ts_init_subtest "umount" ts_valgrind $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>&1 grep -q $DEVICE $LIBMOUNT_UTAB && \ @@ -94,6 +98,8 @@ if [ -x "/sbin/mkfs.btrfs" ]; then /sbin/btrfsctl -S sub $MOUNTPOINT &> /dev/null umount $MOUNTPOINT &> /dev/null + sleep 1 + ts_init_subtest "mount-uhelper-subvol" mkdir -p $MOUNTPOINT &> /dev/null ts_valgrind $TESTPROG --mount -o uhelper=foo,rw,subvol=sub $DEVICE $MOUNTPOINT >> $TS_OUTPUT 2>&1 @@ -105,6 +111,8 @@ if [ -x "/sbin/mkfs.btrfs" ]; then $TS_CMD_FINDMNT --mtab $MOUNTPOINT -o OPTIONS -n >> $TS_OUTPUT 2>&1 ts_log "---" + sleep 1 + ts_init_subtest "umount-subvol" ts_valgrind $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>&1 grep -q $DEVICE $LIBMOUNT_UTAB && \ diff --git a/tests/ts/libmount/files/fstab b/tests/ts/libmount/files/fstab index 2503065..a8f73bc 100644 --- a/tests/ts/libmount/files/fstab +++ b/tests/ts/libmount/files/fstab @@ -10,3 +10,5 @@ proc /proc proc defaults 0 0 foo.com:/mnt/share /mnt/remote nfs noauto //bar.com/gogogo /mnt/gogogo cifs user=SRGROUP/baby,noauto + +/dev/foo /any/foo/ auto defaults 0 0 diff --git a/tests/ts/libmount/tabfiles b/tests/ts/libmount/tabfiles index 7f4913e..671c649 100755 --- a/tests/ts/libmount/tabfiles +++ b/tests/ts/libmount/tabfiles @@ -47,6 +47,16 @@ ts_valgrind $TESTPROG --find-forward "$TS_SELF/files/fstab" target /home/foo &> sed -i -e 's/fs: 0x.*/fs:/g' $TS_OUTPUT ts_finalize_subtest +ts_init_subtest "find-target2" +ts_valgrind $TESTPROG --find-forward "$TS_SELF/files/fstab" target /any/foo &> $TS_OUTPUT +sed -i -e 's/fs: 0x.*/fs:/g' $TS_OUTPUT +ts_finalize_subtest + +ts_init_subtest "find-target3" +ts_valgrind $TESTPROG --find-forward "$TS_SELF/files/fstab" target /any/foo/ &> $TS_OUTPUT +sed -i -e 's/fs: 0x.*/fs:/g' $TS_OUTPUT +ts_finalize_subtest + ts_init_subtest "find-pair" ts_valgrind $TESTPROG --find-pair "$TS_SELF/files/mtab" /dev/mapper/kzak-home /home/kzak &> $TS_OUTPUT sed -i -e 's/fs: 0x.*/fs:/g' $TS_OUTPUT diff --git a/tests/ts/mount/fstab-none b/tests/ts/mount/fstab-none new file mode 100755 index 0000000..62a89ca --- /dev/null +++ b/tests/ts/mount/fstab-none @@ -0,0 +1,30 @@ +#!/bin/bash + +TS_TOPDIR="$(dirname $0)/../.." +TS_DESC="none" + +. $TS_TOPDIR/functions.sh +ts_init "$*" +ts_skip_nonroot + +set -o pipefail + +ts_fstab_add "none" "$TS_MOUNTPOINT" "tmpfs" "rw,nosuid,nodev,relatime" + +mkdir -p $TS_MOUNTPOINT + +$TS_CMD_MOUNT $TS_MOUNTPOINT 2>&1 >> $TS_OUTPUT + +$TS_CMD_FINDMNT --target "$TS_MOUNTPOINT" &> /dev/null +[ $? -eq 0 ] || ts_die "Not found target (mount failed?)" + +$TS_CMD_FINDMNT --source "none" --target "$TS_MOUNTPOINT" &> /dev/null +[ $? -eq 0 ] || ts_die "Not found source and target" + +$TS_CMD_UMOUNT $TS_MOUNTPOINT || ts_die "Cannot umount $TS_MOUNTPOINT" + +ts_fstab_clean + +ts_log "Success" +ts_finalize + diff --git a/tests/ts/mount/shared-subtree b/tests/ts/mount/shared-subtree new file mode 100755 index 0000000..a0a76c5 --- /dev/null +++ b/tests/ts/mount/shared-subtree @@ -0,0 +1,58 @@ +#!/bin/bash + +TS_TOPDIR="$(dirname $0)/../.." +TS_DESC="shared-subtree" + +. $TS_TOPDIR/functions.sh +ts_init "$*" +ts_skip_nonroot + +function get_attr() +{ + # It's usually stupid idea to use 'grep | awk', + # but use paths in awk /regex/ is too tricky... + # + # TODO; improve libmount and findmnt to return the + # shared-subtree flags + # + echo $(grep "$1" /proc/self/mountinfo | \ + awk '{print $7}' | \ + awk -F ':' '{ print $1 }') +} + +[ -d $TS_MOUNTPOINT ] || mkdir -p $TS_MOUNTPOINT + +# bind +$TS_CMD_MOUNT --bind $TS_MOUNTPOINT $TS_MOUNTPOINT + +# check the bind +$TS_CMD_FINDMNT --kernel --target $TS_MOUNTPOINT &> /dev/null +[ "$?" == "0" ] || ts_die "Cannot find binded $TS_MOUNTPOINT in /proc/self/mountinfo" + +# use the same mounpoint for all sub-tests +MOUNTPOINT="$TS_MOUNTPOINT" + + +ts_init_subtest "make-shared" +$TS_CMD_MOUNT --make-shared $MOUNTPOINT >> $TS_OUTPUT 2>&1 +echo "$(get_attr $MOUNTPOINT)" >> $TS_OUTPUT +ts_finalize_subtest + +ts_init_subtest "make-private" +$TS_CMD_MOUNT --make-private $MOUNTPOINT >> $TS_OUTPUT 2>&1 +echo "$(get_attr $MOUNTPOINT)" >> $TS_OUTPUT +ts_finalize_subtest + +ts_init_subtest "make-unbindable" +$TS_CMD_MOUNT --make-unbindable $MOUNTPOINT >> $TS_OUTPUT 2>&1 +echo "$(get_attr $MOUNTPOINT)" >> $TS_OUTPUT +ts_finalize_subtest + + +# clean up +$TS_CMD_UMOUNT $TS_MOUNTPOINT +rmdir $TS_MOUNTPOINT + +ts_log "Success" +ts_finalize +