How to understand the pid() and new_pid are same value in executing forktracker.stp? - linux

I am using forktracker.stp to track the fork process flow. The script is like this:
probe kprocess.create
{
printf("%-25s: %s (%d) created %d\n",
ctime(gettimeofday_s()), execname(), pid(), new_pid)
}
probe kprocess.exec
{
printf("%-25s: %s (%d) is exec'ing %s\n",
ctime(gettimeofday_s()), execname(), pid(), filename)
}
Executing the script, I find it outputs the following results:
......
Thu Oct 22 05:09:42 2015 : virt-manager (8713) created 8713
Thu Oct 22 05:09:42 2015 : virt-manager (8713) created 8713
Thu Oct 22 05:09:42 2015 : virt-manager (8713) created 8713
Thu Oct 22 05:09:43 2015 : virt-manager (8713) created 8713
......
I can't understand why pid() and new_pid are same value. I doubt whether it is related to "fork call once, return twice". So I write a simple program to test:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0) {
exit(1);
} else if (pid > 0) {
printf("Parent exits!\n");
exit(0);
}
printf("hello world\n");
return 0;
}
Tracking this program, the script outputs:
Thu Oct 22 05:27:10 2015 : bash (3855) created 8955
Thu Oct 22 05:27:10 2015 : bash (8955) is exec'ing "./test"
Thu Oct 22 05:27:10 2015 : test (8955) created 8956
So it seems not related to "fork call once, return twice".
How can I understand the pid() and new_pid are same value?

I think what you're seeing are simply new threads, where the pids will be the same while the tids will differ. You can easily add tids to that script like so:
probe kprocess.create {
printf("%-25s: %s (%d:%d) created %d:%d\n",
ctime(gettimeofday_s()), execname(), pid(), tid(), new_pid, new_tid)
}
probe kprocess.exec {
printf("%-25s: %s (%d) is exec'ing %s\n",
ctime(gettimeofday_s()), execname(), pid(), filename)
}
You could also report tid in the exec, but that's often less interesting since an exec will replace the whole process anyway.
(This question was also posted to the mailing list, and I replied here.)

Related

Write to a sysfs node, causing the system always write to the node

I locally wirte a module to test function/feature, And I create follow node info:
/sys/class/dbc/dbc # ls -l
total 0
-rw------- 1 root root 4096 2021-10-08 21:52 dbc_backlight
-rw------- 1 root root 4096 2021-10-08 22:30 dbc_pwm_max
-rw------- 1 root root 4096 2021-10-08 22:30 dbc_pwm_min
-rw------- 1 root root 4096 2021-10-08 21:52 dbc_setting
-rw------- 1 root root 4096 2021-10-08 21:52 dbc_thread_enable
-r--r--r-- 1 root root 4096 2021-10-08 22:30 dev
drwxr-xr-x 2 root root 0 2021-10-08 22:30 power
lrwxrwxrwx 1 root root 0 2021-10-08 22:30 subsystem -> ../../../../class/dbc
-rw-r--r-- 1 root root 4096 2021-10-08 22:30 uevent
when I echo right value to dbc_backlight node, can normally work, but when I write error value to dbc_backlight node, will result always write, info is follow:
node source code is follow:
static ssize_t dbc_backlight_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned int DBC_BACKLIGHT = 0;
int readCount = 0;
printk("===========Set DBC Backlight========\n");
readCount = sscanf(buf, "%d", &DBC_BACKLIGHT);
if (readCount != 1)
{
printk("[ERROR] cannot read DBC_BACKLIGHT from [%s] \n", buf);
return 0;
}
if (DBC_BACKLIGHT > 100)
{
printk("Invalid Parameter DBC_BACKLIGHT=%d \n", DBC_BACKLIGHT);
return 0;
}
printk("Set Parameter DBC_BACKLIGHT=%d success\n", DBC_BACKLIGHT);
m_u8BacklightSetting = DBC_BACKLIGHT;
SetActiveBacklightSwitch(m_eActiveBackLight, m_u8BacklightSetting);
return count;
}
abnormal status dmesg log info is:
[ 2562.416693] ===========Set DBC Backlight========
[ 2562.416739] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.416786] ===========Set DBC Backlight========
[ 2562.416832] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.416878] ===========Set DBC Backlight========
[ 2562.416960] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.417006] ===========Set DBC Backlight========
[ 2562.417089] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.417135] ===========Set DBC Backlight========
[ 2562.417181] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.417265] ===========Set DBC Backlight========
[ 2562.417309] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.417391] ===========Set DBC Backlight========
[ 2562.417436] Invalid Parameter DBC_BACKLIGHT=101
[ 2562.417481] ===========Set DBC Backlight========
[ 2562.417564] Invalid Parameter DBC_BACKLIGHT=101
the log will always running and can't stop, otherwise, kill -9 pid can kill(kill pid can't kill it), top info is follow:
Tasks: 410 total, 2 running, 349 sleeping, 0 stopped, 0 zombie
Mem: 1694992k total, 1583088k used, 111904k free, 12844k buffers
Swap: 409596k total, 13056k used, 396540k free, 732388k cached
400%cpu 6%user 102%nice 135%sys 157%idle 0%iow 0%irq 0%sirq 0%host
PID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ ARGS
2272 logd 30 10 34M 9.4M 4.1M S 152 0.5 2:29.57 logd
10181 root 20 0 4.4M 2.3M 1.9M R 98.6 0.1 1:33.14 sh -
kill -9 10181 can stop thread running.
I don't know why always write the node(dbc_backlight), please help me.
And locally, I do follow modify, the problem will not reproduce:
printk("===========Set DBC Backlight========\n");
readCount = sscanf(buf, "%d", &DBC_BACKLIGHT);
if (readCount != 1)
{
printk("[ERROR] cannot read DBC_BACKLIGHT from [%s] \n", buf);
return 0;
}
if (DBC_BACKLIGHT > 100)
{
printk("Invalid Parameter DBC_BACKLIGHT=%d \n", DBC_BACKLIGHT);
return 0;
}
//modify follow will fix it the problem
printk("===========Set DBC Backlight========\n");
readCount = sscanf(buf, "%d", &DBC_BACKLIGHT);
if (readCount != 1)
{
printk("[ERROR] cannot read DBC_BACKLIGHT from [%s] \n", buf);
return -EINVAL; //........
}
if (DBC_BACKLIGHT > 100)
{
printk("Invalid Parameter DBC_BACKLIGHT=%d \n", DBC_BACKLIGHT);
return -EINVAL;........
}
Do you know why? thanks for your help.
On success, .store function should return number of characters written.
In fail, it should return negative error code.
Returning 0 (return 0;) from that function is incorrect.
As you correctly noted, you can use return -EINVAL; for indicate that input is invalid.

No permissions to change tty mode inside a docker container

I'm trying to run some software inside a docker container, which wants to do VT_SETMODE for the tty currently in use. This will always fail with an error saying "Operation not permitted".
I've tried playing around with permissions/groups with no luck.
Finally I created a small snippet to reproduce the error:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
int main() {
const char *tty_path;
tty_path = "/dev/tty1";
int fd = open(tty_path, O_RDWR | O_CLOEXEC);
if (fd < 0) {
printf("ERROR: Failed to open %s\n", strerror(errno));
return 1;
}
struct vt_mode mode = {
.mode = VT_AUTO,
};
errno = 0;
ioctl(fd, VT_SETMODE, &mode);
if (errno) {
printf("ERROR: %s\n", strerror(errno));
return 1;
}
return 0;
}
I ran the code inside a docker container with a simple dockerfile:
FROM archlinux/base
RUN pacman -Sy --noconfirm gcc
That was started with command:
docker build -f Dockerfile -t tty-test . && docker run --device /dev/tty1 -v $HOME/tty-test:/volume -it tty-test /bin/bash -c 'cd /volume && gcc tty_r.c && ./a.out ; /bin/bash'
Output is this:
ERROR: Operation not permitted
Can anyone explain why the tty is not accessible from the container, or is there some way to give more control to the container?
Okay it seems that I have solved my own problem. I was trying to run the code inside a container which had no privilege to do tty-configuration. Adding --cap-add SYS_TTY_CONFIG to the docker run command fixed the issue.

How to remove forwarding timestamp? OSE version Syslog-NG

Following the answer,
I have tried making changes in Syslog-NG 3.17 OSE version, with below configuration,
#version: 3.17
#include "scl.conf"
options {
};
source s_network_to_forward {
network(
flags(no-parse)
transport(udp)
port(514)
keep-timestamp(no)
persist-name("somekey")
);
};
template forward_template {
template($RAWMSG);
template_escape(no);
};
destination forward_to_syslog2{
network("1.2.3.4" transport(udp) port(514) template(forward_template));
};
log {
source(s_network_to_forward);
destination(forward_to_syslog2);
};
Message to forward: Oct 31 16:44:29.071 UTC: %SYS-3-DUP_TIMER: Same tty2 in linewatch_timers, type 2
Above configuration is able to forward the message as shown below(with extra header in bold):
Oct 31 12:44:29 X.X.X.X 5277586: Oct 31 16:44:29.071 UTC: %SYS-3-DUP_TIMER: Same tty2 in linewatch_timers, type 2
where X.X.X.X is showing actual sender address(as expected), process id(5277586) and forwarding timestamp(Oct 31 12:44:29)
but
expecting to forward only Oct 31 16:44:29.071 UTC: X.X.X.X 5277586: %SYS-3-DUP_TIMER: Same tty2 in linewatch_timers, type 2
by removing forwarding timestamp
How to forward the required format?
If you want to forward the message as it was sent, the $RAWMESSAGE macro is a good idea, but by default it is empty (as it makes a message memory footprint larger).
You have to add an extra flag flags(...,store-raw-message) in the source configuration. (see the related documentation)
Your configuration would look like something this:
#version: 3.17
#include "scl.conf"
options {
};
source s_network_to_forward {
network(
flags(no-parse,store-raw-message)
transport(udp)
port(514)
keep-timestamp(no)
persist-name("somekey")
);
};
template forward_template {
template("$RAWMSG");
template_escape(no);
};
destination forward_to_syslog2{
network("1.2.3.4" transport(udp) port(514) template(forward_template));
};
log {
source(s_network_to_forward);
destination(forward_to_syslog2);
};

Why linux reuses 'time_wait' port?

As I know, tcp port in 'time_wait' stat cann't be used. However, in my experiment, server reuses the 'time_wait' port? Why?
Firstly, in client machine, type command ehco 40000 40001 > /proc/sys/net/ipv4/ip_local_port_range. So, the maximum number of TCP ports is 2.
server code
while (1) {
int len = sizeof(struct sockaddr);
fd = accept(sfd, &remote, &len);
read(fd, buf, sizeof(buf));
close(fd);
}
client code
for (i = 0; i < 3; i++)
{
sleep(1);
pid_t pid = fork();
if (pid == 0)
{
handler();
exit(0);
}
}
void handler()
{
* ............. */
res = connect(sfd, result->ai_addr, result->ai_addrlen);
if (res == -1) {
perror("error");
exit(1);
}
printf("connect\n");
}
show
[root#livecd ~]# ./client
connect
[root#livecd ~]# connect
connect
It's up to 3 connections. I think, 2 connections at most. Why ?
server has 2 timewait connections.
[root#livecd ~]# netstat -anp | grep TIME
tcp 192.168.88.131:2016 192.168.88.132:40000 TIME_WAIT
tcp 192.168.88.131:2016 192.168.88.132:40001 TIME_WAIT
Environment
Linux livecd.centos 2.6.32-642.el6.i686 #1 SMP Tue May 10 16:13:51 UTC 2016
server config
[root#livecd ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
[root#livecd ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle
0
[root#livecd ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
0
client config
[root#livecd ~]# cat /proc/sys/net/ipv4/ip_local_port_range
40000 40001
Important
I also try ubuntu server 14.04, but got the same result.

How can I write to TTY from a kernel module?

First post to SO, so I'll try to make the question right.
I'm making a simple Linux kernel module with the goal of echoing data back to the TTY shell from where the kernel module was loaded. The problem I having is the kernel "Ooops"-ing with the following message (caught with " watch 'dmesg | tail -50' "). The kernel module's name is Seraphim:
[ 184.222748] SELinux: initialized (dev proc, type proc), uses genfs_contexts
[ 1877.456607] seraphim: module verification failed: signature and/or required key missing - tainting kernel
[ 1877.457321] ------------------
[ 1877.457324] Seraphim started.
[ 1877.457348] BUG: unable to handle kernel NULL pointer dereference at 0000000000000218
[ 1877.457411] IP: [<ffffffffa0012030>] seraphim_entry+0x30/0x1000 [seraphim]
[ 1877.457462] PGD 115a2e067 PUD 10aca8067 PMD 0
[ 1877.457498] Oops: 0000 [#1] SMP
[ 1877.457524] Modules linked in: seraphim(OF+) rfcomm bnep nf_conntrack_netbios_ns nf_conn track_broadcast ipt_MASQUERADE ip6t_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llce btable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_ma etc.
The code used for writing data to the TTY terminal follows:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
static void printString(char *string) {
struct tty_struct *tty;
tty = current->signal->tty;
if(tty != NULL) {
(tty->driver->ops->write) (tty, string, strlen(string));
}
else
printk("tty equals to zero");
}
What am I doing wrong?
I was following the tutorial at http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf but it was out of date (the kernel I am using is 3.11.10-200 on Fedora 19), so I had to rummage through 3.11.10-200 source files to find the adequate structures.
use tty = get_current_tty(); instead of tty = current->signal->tty;
that's it
you need to lock the tty before accessing it and get_current_tty does it internally
NOTE: get_current_tty is under EXPORT_SYMBOL_GPL, hence your module or code

Resources