From c3892b38a6ea02c81ae6350e27405718cb1695a2 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Wed, 22 Apr 2015 08:10:46 +0200 Subject: [PATCH] PR18184: Test coverage improvements, tapset extension. * tapset/linux/aux_syscalls.stp: Add auxiliary functions for quotactl tapset. * tapset/linux/nd_syscalls2.stp: Fix types for personality tapset, extend argstr for quotactl. * tapset/linux/syscalls2.stp: Ditto. * tapset/linux/syscalls.stpm: New macro @__quotactl_argstr(). * testsuite/systemtap.syscall/personality.c: New testcase. * testsuite/systemtap.syscall/pivot_root.c: New testcase. * testsuite/systemtap.syscall/quotactl.c: Testcase extension. --- tapset/linux/aux_syscalls.stp | 78 ++++++++++++++++++++++- tapset/linux/nd_syscalls2.stp | 11 ++-- tapset/linux/syscalls.stpm | 36 +++++++++++ tapset/linux/syscalls2.stp | 11 ++-- testsuite/systemtap.syscall/personality.c | 24 +++++++ testsuite/systemtap.syscall/pivot_root.c | 31 +++++++++ testsuite/systemtap.syscall/quotactl.c | 43 ++++++++++--- 7 files changed, 215 insertions(+), 19 deletions(-) create mode 100644 testsuite/systemtap.syscall/personality.c create mode 100644 testsuite/systemtap.syscall/pivot_root.c diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 7934fe9b9..20a8f58dd 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -2289,7 +2289,7 @@ static const _stp_val_array const _stp_quotactl_cmd_list[] = { %} function _quotactl_cmd_str:string(cmd:long) -%{ +%{ /* pure */ unsigned int cmd = (unsigned int)STAP_ARG_cmd >> SUBCMDSHIFT; unsigned int type = (unsigned int)STAP_ARG_cmd & SUBCMDMASK; @@ -2306,6 +2306,82 @@ function _quotactl_cmd_str:string(cmd:long) } %} +function _quotactl_subcmd:long(cmd:long) +%{ /* pure */ + STAP_RETVALUE = (unsigned int)STAP_ARG_cmd >> SUBCMDSHIFT; +%} + + +%{ +static const _stp_val_array const _stp_quotactl_format_list[] = { + V(QFMT_VFS_OLD), +#ifdef QFMT_VFS_V0 + V(QFMT_VFS_V0), +#endif +#ifdef QFMT_OCFS2 + V(QFMT_OCFS2), +#endif +#ifdef QFMT_VFS_V1 + V(QFMT_VFS_V1), +#endif + {0, NULL} +}; +%} + +function _quotactl_quota_type_str:string(fmt:long) +%{ /* pure */ + _stp_lookup_str(_stp_quotactl_format_list, + (int)STAP_ARG_fmt, STAP_RETVALUE, MAXSTRINGLEN); +%} + +function _struct_dqblk_u:string(uaddr:long) +%{ /* pure */ + struct if_dqblk dqb; + char *ptr = (char *)(unsigned long)STAP_ARG_uaddr; + if (ptr == NULL) + strlcpy (STAP_RETVALUE, "NULL", MAXSTRINGLEN); + else + { + if (_stp_copy_from_user((char*)&dqb, ptr, + sizeof(struct if_dqblk)) == 0) + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, + "{dqb_bhardlimit=%llu, dqb_bsoftlimit=%llu, dqb_curspace=%llu, dqb_ihardlimit=%llu, dqb_isoftlimit=%llu, ...}", + (unsigned long long)dqb.dqb_bhardlimit, (unsigned long long)dqb.dqb_bsoftlimit, (unsigned long long)dqb.dqb_curspace, + (unsigned long long)dqb.dqb_ihardlimit, (unsigned long long)dqb.dqb_isoftlimit); + } + else + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, "0x%lx", + (unsigned long)ptr); + } + } +%} + +function _struct_dqinfo_u:string(uaddr:long) +%{ /* pure */ + struct if_dqinfo dqi; + char *ptr = (char *)(unsigned long)STAP_ARG_uaddr; + if (ptr == NULL) + strlcpy (STAP_RETVALUE, "NULL", MAXSTRINGLEN); + else + { + if (_stp_copy_from_user((char*)&dqi, ptr, + sizeof(struct if_dqinfo)) == 0) + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, + "{dqi_bgrace=%llu, dqi_igrace=%llu, dqi_flags=%d, dqi_valid=%d}", + (unsigned long long)dqi.dqi_bgrace, (unsigned long long)dqi.dqi_igrace, + dqi.dqi_flags, dqi.dqi_valid); + } + else + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, "0x%lx", + (unsigned long)ptr); + } + } +%} + %{ #include diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index 838071ba1..83f0e7391 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -336,14 +336,16 @@ probe nd_syscall.pause.return = kprobe.function("sys_pause").return ?, # personality ________________________________________________ # # asmlinkage long -# sys_personality(u_long personality) +# sys_personality(unsigned int personality) +# personality type changed from ulong to uint32 in upstream commit 485d5276 +# (v2.6.35-rc2~25). But rhel6 distribution kernel has the backport in 2.6.32. # probe nd_syscall.personality = kprobe.function("sys_personality") ? { name = "personality" asmlinkage() - persona = ulong_arg(1) - argstr = sprintf("%p", persona); + persona = uint_arg(1) + argstr = sprintf("%#x", persona); } probe nd_syscall.personality.return = kprobe.function("sys_personality").return ? { @@ -856,8 +858,7 @@ probe nd_syscall.quotactl = __nd_syscall.quotactl ?, special_str = user_string_quoted(special) id = int_arg(3) addr_uaddr = pointer_arg(4) - argstr = sprintf("%s, %s, %d, %p", cmd_str, special_str, id, - addr_uaddr) + @__quotactl_argstr(_quotactl_subcmd(cmd), cmd, special, id, addr_uaddr) } probe __nd_syscall.quotactl = kprobe.function("sys_quotactl") ? { diff --git a/tapset/linux/syscalls.stpm b/tapset/linux/syscalls.stpm index 78feddb1f..1bfa4b2be 100644 --- a/tapset/linux/syscalls.stpm +++ b/tapset/linux/syscalls.stpm @@ -252,5 +252,41 @@ } %) +@define __quotactl_argstr(subcmd, arg1, arg2, arg3, arg4) +%( + if (@subcmd == %{ /* pure */ Q_QUOTAON %}) { + argstr = sprintf("%s, %s, %s, %s", + _quotactl_cmd_str(@arg1), user_string_quoted(@arg2), + _quotactl_quota_type_str(@arg3), + user_string_quoted(@arg4)) + } + else if ((@subcmd == %{ /* pure */ Q_GETQUOTA %}) || + (@subcmd == %{ /* pure */ Q_SETQUOTA %})) { + argstr = sprintf("%s, %s, %d, %s", + _quotactl_cmd_str(@arg1), user_string_quoted(@arg2), + @arg3, _struct_dqblk_u(@arg4)) + } + else if ((@subcmd == %{ /* pure */ Q_GETINFO %}) || + (@subcmd == %{ /* pure */ Q_SETINFO %})) { + argstr = sprintf("%s, %s, %d, %s", + _quotactl_cmd_str(@arg1), user_string_quoted(@arg2), + @arg3, _struct_dqinfo_u(@arg4)) + } + else if (@subcmd == %{ /* pure */ Q_GETFMT %}) { + argstr = sprintf("%s, %s, %d, %x", + _quotactl_cmd_str(@arg1), user_string_quoted(@arg2), + @arg3, @arg4) + } + else if ((@subcmd == %{ /* pure */ Q_SYNC %}) || + (@subcmd == %{ /* pure */ Q_QUOTAOFF %})) { + argstr = sprintf("%s, %s, %d, %p", + _quotactl_cmd_str(@arg1), user_string_quoted(@arg2), + @arg3, @arg4) + } + else { + argstr = sprintf("%s, %p, %d, %p", _quotactl_cmd_str(@arg1), + @arg2, @arg3, @arg4) + } +%) diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index 1e696f938..88e565ecd 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -333,13 +333,15 @@ probe syscall.pause.return = kernel.function("sys_pause").return ?, # personality ________________________________________________ # # asmlinkage long -# sys_personality(u_long personality) +# sys_personality(unsigned int personality) +# personality type changed from ulong to uint32 in upstream commit 485d5276 +# (v2.6.35-rc2~25). But rhel6 distribution kernel has the backport in 2.6.32. # probe syscall.personality = kernel.function("sys_personality").call { name = "personality" - persona = $personality - argstr = sprintf("%p", persona); + persona = __uint32($personality) + argstr = sprintf("%#x", persona); } probe syscall.personality.return = kernel.function("sys_personality").return { @@ -881,8 +883,7 @@ probe syscall.quotactl = __syscall.quotactl ?, special_str = user_string_quoted($special) id = __int32($id) addr_uaddr = $addr - argstr = sprintf("%s, %s, %d, %p", cmd_str, special_str, - __int32($id), $addr) + @__quotactl_argstr(_quotactl_subcmd(cmd), cmd, special, id, addr_uaddr) } probe __syscall.quotactl = kernel.function("sys_quotactl").call ? { diff --git a/testsuite/systemtap.syscall/personality.c b/testsuite/systemtap.syscall/personality.c new file mode 100644 index 000000000..443c22170 --- /dev/null +++ b/testsuite/systemtap.syscall/personality.c @@ -0,0 +1,24 @@ +/* COVERAGE: personality */ + +#include +#include + +int main() +{ + // The type of personality argument changed in upstream + // commit 485d5276 from ulong to uint32. This patch is + // present in vanila kernel v2.6.35-rc2~25. But apparently + // it got backported to rhel6 distribution kernels 2.6.32. + // So expecting uint32 here and letting this fail on rhel5. + + personality(0xffffffff); + //staptest// personality (0xffffffff) = NNNN + + personality(0x12345678); + //staptest// personality (0x12345678) = NNNN + + personality(-1); + //staptest// personality (0xffffffff) = NNNN + + return 0; +} diff --git a/testsuite/systemtap.syscall/pivot_root.c b/testsuite/systemtap.syscall/pivot_root.c new file mode 100644 index 000000000..fed369619 --- /dev/null +++ b/testsuite/systemtap.syscall/pivot_root.c @@ -0,0 +1,31 @@ +/* COVERAGE: pivot_root */ + +#define _GNU_SOURCE +#include +#include + +int main() +{ + + // We are not really going to let the syscall succeed. + // Just sanity check it: + + syscall(__NR_pivot_root, "/tmp", "/"); + //staptest// pivot_root ("/tmp", "/") = NNNN + + syscall(__NR_pivot_root, (const char *)-1, "/tmp"); +#ifdef __s390__ + //staptest// pivot_root ([7]?[f]+, "/tmp") = NNNN +#else + //staptest// pivot_root ([f]+, "/tmp") = NNNN +#endif + + syscall(__NR_pivot_root, "/tmp", (const char *)-1); +#ifdef __s390__ + //staptest// pivot_root ("/tmp", [7]?[f]+) = NNNN +#else + //staptest// pivot_root ("/tmp", [f]+) = NNNN +#endif + + return 0; +} diff --git a/testsuite/systemtap.syscall/quotactl.c b/testsuite/systemtap.syscall/quotactl.c index 121d81e7e..ea02c803c 100644 --- a/testsuite/systemtap.syscall/quotactl.c +++ b/testsuite/systemtap.syscall/quotactl.c @@ -6,10 +6,18 @@ #include //#include + +#ifndef QFMT_VFS_V0 +#define QFMT_VFS_V0 2 +#endif + + int main() { struct dqblk dqblk; + struct dqinfo dqinfo; uid_t uid; + int qfmt; // Note that these calls will fail for a couple of reasons: // 1) You have to be root to run quotactl() @@ -18,25 +26,43 @@ int main() // anyway. uid = getuid(); - quotactl(QCMD(Q_GETQUOTA, USRQUOTA), NULL, uid, (caddr_t)&dqblk); - //staptest// quotactl (Q_GETQUOTA|USRQUOTA, *(null), NNNN, XXXX) = -NNNN + quotactl(QCMD(Q_QUOTAON, USRQUOTA), "somedevice", QFMT_VFS_V0, "staptestmnt/aquota.user"); + //staptest// quotactl (Q_QUOTAON|USRQUOTA, "somedevice", QFMT_VFS_V0, "staptestmnt/aquota.user") = -NNNN + + quotactl(QCMD(Q_GETQUOTA, USRQUOTA), "somedevice", getuid(), (caddr_t)&dqblk); + //staptest// quotactl (Q_GETQUOTA|USRQUOTA, "somedevice", NNNN, {dqb_bhardlimit=NNNN, dqb_bsoftlimit=NNNN, dqb_curspace=NNNN, dqb_ihardlimit=NNNN, dqb_isoftlimit=NNNN, ...}) = -NNNN + + quotactl(QCMD(Q_SETQUOTA, USRQUOTA), "somedevice", getuid(), (caddr_t)&dqblk); + //staptest// quotactl (Q_SETQUOTA|USRQUOTA, "somedevice", NNNN, {dqb_bhardlimit=NNNN, dqb_bsoftlimit=NNNN, dqb_curspace=NNNN, dqb_ihardlimit=NNNN, dqb_isoftlimit=NNNN, ...}) = -NNNN - quotactl(QCMD(Q_SYNC, GRPQUOTA), NULL, 0, NULL); - //staptest// quotactl (Q_SYNC|GRPQUOTA, *(null), 0, 0x0) = NNNN + quotactl(QCMD(Q_GETINFO, USRQUOTA), "somedevice", getuid(), (caddr_t)&dqinfo); + //staptest// quotactl (Q_GETINFO|USRQUOTA, "somedevice", NNNN, {dqi_bgrace=NNNN, dqi_igrace=NNNN, dqi_flags=NNNN, dqi_valid=NNNN}) = -NNNN + + quotactl(QCMD(Q_SETINFO, USRQUOTA), "somedevice", getuid(), (caddr_t)&dqinfo); + //staptest// quotactl (Q_SETINFO|USRQUOTA, "somedevice", NNNN, {dqi_bgrace=NNNN, dqi_igrace=NNNN, dqi_flags=NNNN, dqi_valid=NNNN}) = -NNNN + + quotactl(QCMD(Q_GETFMT, USRQUOTA), "somedevice", getuid(), (caddr_t)&qfmt); + //staptest// quotactl (Q_GETFMT|USRQUOTA, "somedevice", NNNN, XXXX) = -NNNN + + quotactl(QCMD(Q_SYNC, USRQUOTA), "somedevice", 0, NULL); + //staptest// quotactl (Q_SYNC|USRQUOTA, "somedevice", 0, 0x0) = -NNNN + + quotactl(QCMD(Q_QUOTAOFF, USRQUOTA), "somedevice", 0, NULL); + //staptest// quotactl (Q_QUOTAOFF|USRQUOTA, "somedevice", 0, 0x0) = -NNNN /* Limit testing. */ quotactl(-1, NULL, uid, (caddr_t)&dqblk); - //staptest// quotactl (XXXX|XXXX, *(null), NNNN, XXXX) = -NNNN + //staptest// quotactl (XXXX|XXXX, 0x0, NNNN, XXXX) = -NNNN quotactl(QCMD(Q_GETQUOTA, USRQUOTA), (char *)-1, uid, (caddr_t)&dqblk); #ifdef __s390__ - //staptest// quotactl (Q_GETQUOTA|USRQUOTA, [7]?[f]+, NNNN, XXXX) = -NNNN + //staptest// quotactl (Q_GETQUOTA|USRQUOTA, [7]?[f]+, NNNN, {dqb_bhardlimit=NNNN, dqb_bsoftlimit=NNNN, dqb_curspace=NNNN, dqb_ihardlimit=NNNN, dqb_isoftlimit=NNNN, ...}) = -NNNN #else - //staptest// quotactl (Q_GETQUOTA|USRQUOTA, [f]+, NNNN, XXXX) = -NNNN + //staptest// quotactl (Q_GETQUOTA|USRQUOTA, [f]+, NNNN, {dqb_bhardlimit=NNNN, dqb_bsoftlimit=NNNN, dqb_curspace=NNNN, dqb_ihardlimit=NNNN, dqb_isoftlimit=NNNN, ...}) = -NNNN #endif quotactl(QCMD(Q_GETQUOTA, USRQUOTA), NULL, -1, (caddr_t)&dqblk); - //staptest// quotactl (Q_GETQUOTA|USRQUOTA, *(null), -1, XXXX) = -NNNN + //staptest// quotactl (Q_GETQUOTA|USRQUOTA, *(null), -1, {dqb_bhardlimit=NNNN, dqb_bsoftlimit=NNNN, dqb_curspace=NNNN, dqb_ihardlimit=NNNN, dqb_isoftlimit=NNNN, ...}) = -NNNN quotactl(QCMD(Q_GETQUOTA, USRQUOTA), NULL, uid, (caddr_t)-1); #ifdef __s390__ @@ -44,5 +70,6 @@ int main() #else //staptest// quotactl (Q_GETQUOTA|USRQUOTA, *(null), NNNN, 0x[f]+) = -NNNN #endif + return 0; } -- 2.43.5