* 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.
%}
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;
}
%}
+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 <linux/socket.h>
# 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 ?
{
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") ?
{
}
%)
+@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)
+ }
+%)
# 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
{
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 ?
{
--- /dev/null
+/* COVERAGE: personality */
+
+#include <sys/personality.h>
+#include <linux/version.h>
+
+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;
+}
--- /dev/null
+/* COVERAGE: pivot_root */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+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;
+}
#include <sys/quota.h>
//#include <xfs/xqm.h>
+
+#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()
// 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__
#else
//staptest// quotactl (Q_GETQUOTA|USRQUOTA, *(null), NNNN, 0x[f]+) = -NNNN
#endif
+
return 0;
}