static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
                              struct pid *pid, struct task_struct *p)
{
    struct user_namespace *user_ns = seq_user_ns(m);
    struct group_info *group_info;
    int g;
    struct fdtable *fdt = NULL;
    const struct cred *cred;
    pid_t ppid, tpid;

    rcu_read_lock();
    ppid = pid_alive(p) ?
           task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
    tpid = 0;
    if (pid_alive(p)) {
        struct task_struct *tracer = ptrace_parent(p);
        if (tracer)
            tpid = task_pid_nr_ns(tracer, ns);
    }
    cred = get_task_cred(p);
    seq_printf(m,
               "State:\t%s\n"
               "Tgid:\t%d\n"
               "Pid:\t%d\n"
               "PPid:\t%d\n"
               "TracerPid:\t%d\n"
               "Uid:\t%d\t%d\t%d\t%d\n"
               "Gid:\t%d\t%d\t%d\t%d\n",
               get_task_state(p),
               task_tgid_nr_ns(p, ns),
               pid_nr_ns(pid, ns),
               ppid, tpid,
               from_kuid_munged(user_ns, cred->uid),
               from_kuid_munged(user_ns, cred->euid),
               from_kuid_munged(user_ns, cred->suid),
               from_kuid_munged(user_ns, cred->fsuid),
               from_kgid_munged(user_ns, cred->gid),
               from_kgid_munged(user_ns, cred->egid),
               from_kgid_munged(user_ns, cred->sgid),
               from_kgid_munged(user_ns, cred->fsgid));

    task_lock(p);
    if (p->files)
        fdt = files_fdtable(p->files);
    seq_printf(m,
               "FDSize:\t%d\n"
               "Groups:\t",
               fdt ? fdt->max_fds : 0);
    rcu_read_unlock();

    group_info = cred->group_info;
    task_unlock(p);

    for (g = 0; g < group_info->ngroups; g++)
        seq_printf(m, "%d ",
                   from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
    put_cred(cred);

    seq_putc(m, '\n');
}
Exemplo n.º 2
0
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;
	const struct cred *cred;
	pid_t ppid, tpid, vpid;

	rcu_read_lock();
	ppid = pid_alive(p) ? ve_task_ppid_nr_ns(p, ns) : 0;

	tpid = 0;
	if (pid_alive(p)) {
		struct task_struct *tracer = tracehook_tracer_task(p);
		if (tracer)
			tpid = task_pid_nr_ns(tracer, ns);
	}
	vpid = task_virtual_pid(p);
	cred = get_task_cred(p);
	seq_printf(m,
		"State:\t%s\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		get_task_state(p),
		task_tgid_nr_ns(p, ns),
		pid_nr_ns(pid, ns),
		ppid, tpid,
		cred->uid, cred->euid, cred->suid, cred->fsuid,
		cred->gid, cred->egid, cred->sgid, cred->fsgid);

	task_utrace_proc_status(m, p);

	task_lock(p);
	if (p->files)
		fdt = files_fdtable(p->files);
	seq_printf(m,
		"FDSize:\t%d\n"
		"Groups:\t",
		fdt ? fdt->max_fds : 0);
	rcu_read_unlock();

	group_info = cred->group_info;
	task_unlock(p);

	for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
		seq_printf(m, "%d ", GROUP_AT(group_info, g));
	put_cred(cred);

	seq_printf(m, "\n");

	seq_printf(m, "envID:\t%d\nVPid:\t%d\n",
			p->ve_task_info.owner_env->veid, vpid);
	seq_printf(m, "StopState:\t%u\n", p->stopped_state);
}
Exemplo n.º 3
0
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;
	pid_t ppid, tpid;

	rcu_read_lock();
	ppid = pid_alive(p) ?
		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
	tpid = 0;
	if (pid_alive(p)) {
		struct task_struct *tracer = tracehook_tracer_task(p);
		if (tracer)
			tpid = task_pid_nr_ns(tracer, ns);
	}
	seq_printf(m,
		"State:\t%s\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		get_task_state(p),
		task_tgid_nr_ns(p, ns),
		pid_nr_ns(pid, ns),
		ppid, tpid,
		p->uid, p->euid, p->suid, p->fsuid,
		p->gid, p->egid, p->sgid, p->fsgid);

	task_lock(p);
	if (p->files)
		fdt = files_fdtable(p->files);
	seq_printf(m,
		"FDSize:\t%d\n"
		"Groups:\t",
		fdt ? fdt->max_fds : 0);
	rcu_read_unlock();

	group_info = p->group_info;
	get_group_info(group_info);
	task_unlock(p);

	for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
		seq_printf(m, "%d ", GROUP_AT(group_info, g));
	put_group_info(group_info);

	seq_printf(m, "\n");
}
Exemplo n.º 4
0
/* count current worker and jobs */
void count_current_worker(int restart) {
    int x;

    gm_log( GM_LOG_TRACE3, "count_current_worker()\n");
    gm_log( GM_LOG_TRACE3, "done jobs:     shm[SHM_JOBS_DONE] = %d\n", shm[SHM_JOBS_DONE]);

    /* shm states:
     *   0 -> undefined
     *  -1 -> free
     * <-1 -> used but idle
     * > 1 -> used and working
     */

    /* check if status worker died */
    if( shm[SHM_STATUS_WORKER_PID] != -1 && pid_alive(shm[SHM_STATUS_WORKER_PID]) == FALSE ) {
        gm_log( GM_LOG_TRACE, "removed stale status worker, old pid: %d\n", shm[SHM_STATUS_WORKER_PID] );
        shm[SHM_STATUS_WORKER_PID] = -1;
    }
    gm_log( GM_LOG_TRACE3, "status worker: shm[SHM_STATUS_WORKER_PID] = %d\n", shm[SHM_STATUS_WORKER_PID]);

    /* check all known worker */
    current_number_of_workers = 0;
    current_number_of_jobs    = 0;
    for(x=SHM_SHIFT; x < mod_gm_opt->max_worker+SHM_SHIFT; x++) {
        /* verify worker is alive */
        gm_log( GM_LOG_TRACE3, "worker slot:   shm[%d] = %d\n", x, shm[x]);
        if( shm[x] != -1 && pid_alive(shm[x]) == FALSE ) {
            gm_log( GM_LOG_TRACE, "removed stale worker %d, old pid: %d\n", x, shm[x]);
            shm[x] = -1;
            /* immediately start new worker, otherwise the fork rate cannot be guaranteed */
            if(restart == GM_ENABLED) {
                make_new_child(GM_WORKER_MULTI);
                current_number_of_workers++;
            }
        }
        if(shm[x] != -1) {
            current_number_of_workers++;
        }
        if(shm[x] > 0) {
            current_number_of_jobs++;
        }
    }

    shm[SHM_WORKER_TOTAL]   = current_number_of_workers; /* total worker   */
    shm[SHM_WORKER_RUNNING] = current_number_of_jobs;    /* running worker */

    gm_log( GM_LOG_TRACE3, "worker: %d  -  running: %d\n", current_number_of_workers, current_number_of_jobs);

    return;
}
Exemplo n.º 5
0
/*
 * Check that the processes holding locks are still alive.
 */
static bool check_lock(lock_t *_lock)
{
	pid_t pid;

	/* We don't care about unlocked or locking-in-progress */
	if (_lock->lock != LOCKED)
		return FALSE;

	/* First the easy case. If it's held by a dead pid, release it. */
	pid = _lock->owner;

	/* if we're in the process of unlocking, it can show up as LOCKED
	 * but with no owner. Just bail, we'll try again next time around.
	 */
	if (pid == 0)
		return FALSE;

	if (pid_alive(pid) == FALSE) {
		if (errno != ESRCH)
			return TRUE;

		debugf("Found a lock held by dead pid %d. Freeing.\n", pid);
		unlock(_lock);
		return TRUE;
	}
	return FALSE;
}
Exemplo n.º 6
0
static void check_lock(lock_t *_lock)
{
	pid_t pid;

	if (_lock->lock != LOCKED)
		return;

	/* First the easy case. If it's held by a dead pid, release it. */
	pid = _lock->owner;
	if (pid_alive(pid) == -1) {
		if (errno != ESRCH)
			return;

		debugf("Found a lock held by dead pid %d. Freeing.\n", pid);
		unlock(_lock);
		return;
	}

	/* If a pid has had a lock a long time, something is up. */
	if (_lock->contention > STEAL_THRESHOLD) {
		debugf("pid %d has held lock for too long. Releasing, and killing.\n", pid);
		kill_pid(pid);
		unlock(_lock);
		return;
	}
	return;
}
Exemplo n.º 7
0
/* send kill to all forked processes */
void kill_child_checks(void) {
    int retval;
    pid_t pid;

    signal(SIGINT, SIG_IGN);
    pid = getpid();
    if(current_child_pid > 0 && current_child_pid != pid) {
        gm_log( GM_LOG_TRACE, "kill_child_checks(): send SIGINT to %d\n", current_child_pid);
        kill(-current_child_pid, SIGINT);
        kill(current_child_pid, SIGINT);
        sleep(1);
        if(waitpid(current_child_pid,&retval,WNOHANG)!=0) {
            signal(SIGINT, SIG_DFL);
            return;
        }
        if(pid_alive(current_child_pid)) {
            gm_log( GM_LOG_TRACE, "kill_child_checks(): send SIGKILL to %d\n", current_child_pid);
            kill(current_child_pid, SIGKILL);
        }
    }
    gm_log( GM_LOG_TRACE, "send SIGINT to %d\n", pid);
    kill(0, SIGINT);
    signal(SIGINT, SIG_DFL);
    return;
}
Exemplo n.º 8
0
/* Main function for TLB walkthrough
 * Check accessed page every Memmap_wakeupsIinterval ms
 */
int Moca_MonitorThread(void * arg)
{
    task_data data;
    moca_task t;
    struct task_struct * task;
    //Init tlb walk data
    int pos;
    unsigned long long lastwake=0;

    MOCA_DEBUG_PRINT("Moca monitor thread alive \n");
    while(!kthread_should_stop())
    {
        pos=0;
        while((t=Moca_NextTask(&pos)))
        {
            data=t->data;
            task=(struct task_struct *)(t->key);
            MOCA_DEBUG_PRINT("Moca monitor thread testing task %p\n", task);
            if(pid_alive(task) && task->sched_info.last_arrival >= lastwake)
            {
                lastwake=task->sched_info.last_arrival;
                MOCA_DEBUG_PRINT("Moca monitor thread found task %p\n",task);
                Moca_MonitorPage(data);
            }
        }
        Moca_UpdateClock();
        MOCA_DEBUG_PRINT("Moca monitor thread going to sleep for %d\n",
                Moca_wakeupInterval);
        msleep(Moca_wakeupInterval);
    }
    MOCA_DEBUG_PRINT("Moca monitor thread finished\n");
    return 0;
}
Exemplo n.º 9
0
// Add pid to the monitored process if pid is a monitored process
moca_task Moca_AddTaskIfNeeded(struct task_struct *t)
{
    moca_task ret=NULL;
    if(t && pid_alive(t) && t->real_parent && Moca_ShouldMonitorTask(t))
        ret=Moca_AddTask(t);
    return ret;
}
Exemplo n.º 10
0
/*
 * Accumulate raw cputime values of dead tasks (sig->[us]time) and live
 * tasks (sum on group iteration) belonging to @tsk's group.
 */
void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
{
	struct signal_struct *sig = tsk->signal;
	cputime_t utime, stime;
	struct task_struct *t;

	times->utime = sig->utime;
	times->stime = sig->stime;
	times->sum_exec_runtime = sig->sum_sched_runtime;

	rcu_read_lock();
	/* make sure we can trust tsk->thread_group list */
	if (!likely(pid_alive(tsk)))
		goto out;

	t = tsk;
	do {
		task_cputime(tsk, &utime, &stime);
		times->utime += utime;
		times->stime += stime;
		times->sum_exec_runtime += task_sched_runtime(t);
	} while_each_thread(tsk, t);
out:
	rcu_read_unlock();
}
Exemplo n.º 11
0
void init_child(int childno)
{
	cpu_set_t set;
	pid_t pid = getpid();
	char childname[17];

	this_child = childno;

	set_seed(childno);

	shm->kill_count[childno] = 0;

	shm->num_mappings[childno] = 0;
	shm->mappings[childno] = zmalloc(sizeof(struct map));
	INIT_LIST_HEAD(&shm->mappings[childno]->list);

	setup_page_maps();

	if (sched_getaffinity(pid, sizeof(set), &set) == 0) {
		CPU_ZERO(&set);
		CPU_SET(childno, &set);
		sched_setaffinity(pid, sizeof(set), &set);
	}

	shm->child_syscall_count[childno] = 0;

	memset(childname, 0, sizeof(childname));
	sprintf(childname, "trinity-c%d", childno);
	prctl(PR_SET_NAME, (unsigned long) &childname);

	oom_score_adj(500);

	/* Wait for parent to set our pidslot */
	while (shm->pids[childno] != getpid()) {
		int ret = 0;

		/* Make sure parent is actually alive to wait for us. */
		ret = pid_alive(shm->mainpid);
		if (ret != 0) {
			shm->exit_reason = EXIT_SHM_CORRUPTION;
			outputerr(BUGTXT "parent (%d) went away!\n", shm->mainpid);
			sleep(20000);
		}
	}

	/* Wait for all the children to start up. */
	while (shm->ready == FALSE)
		sleep(1);

	set_make_it_fail();

	if (rand() % 100 < 50)
		use_fpu();

	mask_signals_child();

	disable_coredumps();
}
Exemplo n.º 12
0
static inline char * task_state(struct task_struct *p, char *buffer)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;

	read_lock(&tasklist_lock);
	buffer += sprintf(buffer,
		"State:\t%s\n"
		"SleepAVG:\t%lu%%\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		get_task_state(p),
		(p->sleep_avg/1024)*100/(1020000000/1024),
	       	p->tgid,
		p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
		pid_alive(p) && p->ptrace ? p->parent->pid : 0,
		p->uid, p->euid, p->suid, p->fsuid,
		p->gid, p->egid, p->sgid, p->fsgid);
	read_unlock(&tasklist_lock);
	task_lock(p);
	rcu_read_lock();
	if (p->files)
		fdt = files_fdtable(p->files);
	buffer += sprintf(buffer,
		"FDSize:\t%d\n"
		"Groups:\t",
		fdt ? fdt->max_fds : 0);
	rcu_read_unlock();

	group_info = p->group_info;
	get_group_info(group_info);
	task_unlock(p);

	for (g = 0; g < min(group_info->ngroups,NGROUPS_SMALL); g++)
		buffer += sprintf(buffer, "%d ", GROUP_AT(group_info,g));
	put_group_info(group_info);

	buffer += sprintf(buffer, "\n");
	return buffer;
}
Exemplo n.º 13
0
static inline void task_state(struct seq_file *m, struct pid *pid,
				struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;

	rcu_read_lock();
	seq_printf(m,
		"State:\t%s\n"
		"SleepAVG:\t%lu%%\n"
		"Tgid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n",
		get_task_state(p),
		(p->sleep_avg/1024)*100/(1020000000/1024),
	       	p->tgid, p->pid,
	       	pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
		pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
		p->uid, p->euid, p->suid, p->fsuid,
		p->gid, p->egid, p->sgid, p->fsgid);

	task_lock(p);
	if (p->files)
		fdt = files_fdtable(p->files);
	seq_printf(m,
		"FDSize:\t%d\n"
		"Groups:\t",
		fdt ? fdt->max_fds : 0);
	rcu_read_unlock();

	group_info = p->group_info;
	get_group_info(group_info);
	task_unlock(p);

	for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
		seq_printf(m, "%d ", GROUP_AT(group_info, g));
	put_group_info(group_info);

	seq_printf(m, "\n");
}
Exemplo n.º 14
0
/* This is a special case for things like execve, which would replace our
 * child process with something unknown to us. We use a 'throwaway' process
 * to do the execve in, and let it run for a max of a second before we kill it
 */
static void do_extrafork(struct syscallrecord *rec)
{
	pid_t pid = 0;
	pid_t extrapid;

	extrapid = fork();
	if (extrapid == 0) {
		/* grand-child */
		char childname[]="trinity-subchild";
		prctl(PR_SET_NAME, (unsigned long) &childname);

		__do_syscall(rec, GOING_AWAY);
		/* if this was for eg. an successful execve, we should never get here.
		 * if it failed though... */
		_exit(EXIT_SUCCESS);
	}

	/* misc failure. */
	if (extrapid == -1) {
		//debugf("Couldn't fork grandchild: %s\n", strerror(errno));
		return;
	}

	/* small pause to let grandchild do some work. */
	if (pid_alive(extrapid) == TRUE)
		usleep(100);

	/* We take the rec lock here even though we don't obviously use it.
	 * The reason, is that the grandchild is using it. */
	lock(&rec->lock);
	while (pid == 0) {
		int childstatus;

		pid = waitpid(extrapid, &childstatus, WUNTRACED | WCONTINUED | WNOHANG);
		if (pid_alive(extrapid) == TRUE)
			kill(extrapid, SIGKILL);
		usleep(1000);
	}
	unlock(&rec->lock);
}
Exemplo n.º 15
0
void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
{
	const struct cred *tcred;
	struct timespec uptime, ts;
	u64 ac_etime;

	BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN);

	
	do_posix_clock_monotonic_gettime(&uptime);
	ts = timespec_sub(uptime, tsk->start_time);
	
	ac_etime = timespec_to_ns(&ts);
	do_div(ac_etime, NSEC_PER_USEC);
	stats->ac_etime = ac_etime;
	stats->ac_btime = get_seconds() - ts.tv_sec;
	if (thread_group_leader(tsk)) {
		stats->ac_exitcode = tsk->exit_code;
		if (tsk->flags & PF_FORKNOEXEC)
			stats->ac_flag |= AFORK;
	}
	if (tsk->flags & PF_SUPERPRIV)
		stats->ac_flag |= ASU;
	if (tsk->flags & PF_DUMPCORE)
		stats->ac_flag |= ACORE;
	if (tsk->flags & PF_SIGNALED)
		stats->ac_flag |= AXSIG;
	stats->ac_nice	 = task_nice(tsk);
	stats->ac_sched	 = tsk->policy;
	stats->ac_pid	 = tsk->pid;
	rcu_read_lock();
	tcred = __task_cred(tsk);
	stats->ac_uid	 = tcred->uid;
	stats->ac_gid	 = tcred->gid;
	stats->ac_ppid	 = pid_alive(tsk) ?
				rcu_dereference(tsk->real_parent)->tgid : 0;
	rcu_read_unlock();
	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
	stats->ac_utimescaled =
		cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC;
	stats->ac_stimescaled =
		cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC;
	stats->ac_minflt = tsk->min_flt;
	stats->ac_majflt = tsk->maj_flt;

	strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm));
}
Exemplo n.º 16
0
static void timer_function(unsigned long par)
{ 
  ushort cpu_share; 

  if (unlikely(!pid_alive(check_task))) {
    del_timer(&check_timer);
    printk(KERN_INFO "sendsig: cannot find pid %i. Is the process still active? Timer removed\n", pid);
    return;
  }

  cpu_share = thread_group_cpu_share(check_task);

  if (cpu_share >= max_cpu_share) {
    count_check++;
    printk(KERN_INFO "sendsig: current cpu share over limit of %i (check #%i)\n", 
	   max_cpu_share, count_check);

/* the ratio is: if the process has a cpu share higher than
   max_cpu_share for more than max_checks * wait_timeout seconds, then
   we'll send the signal sig_to_send to it
 */    
    if (count_check >= max_checks) {
      /*
	sending the signal to the process
      */
      signal_send(check_task);
      /*
	remove the timer
      */ 
      del_timer(&check_timer);
      printk(KERN_INFO "sendsig: sent signal to process %i, timer removed\n", pid);
      return;
    } 
  } else {
    /*
      if the process is being good, let's reset its counter
    */
    count_check = 0;
  }  
  /*
    update the timer
  */
  mod_timer(&check_timer, jiffies + wait_timeout * HZ); 

  return;
}
Exemplo n.º 17
0
static void restart_lost_procs(void)
{
	svc_t *svc;

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		if (svc->pid > 0 && pid_alive(svc->pid))
			continue;

		/* Only restart lost daemons, not task/run/inetd services */
		if (SVC_TYPE_SERVICE != svc->type) {
			svc->pid = 0;
			continue;
		}

		service_start(svc);
	}
}
Exemplo n.º 18
0
static void post_fork(struct syscallrecord *rec)
{
	pid_t pid;

	pid = rec->retval;
	if (pid == 0) {
		// child
		sleep(1);
		_exit(EXIT_SUCCESS);
	} else {
		__unused__ int ret;

		while (pid_alive(pid)) {
			int status;
			ret = waitpid(pid, &status, WUNTRACED | WCONTINUED | WNOHANG);
		}
	}
}
Exemplo n.º 19
0
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct group_info *group_info;
	int g;
	struct fdtable *fdt = NULL;
	const struct cred *cred;
	pid_t ppid, tpid;

	rcu_read_lock();
	ppid = pid_alive(p) ?
		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
	tpid = 0;
	if (pid_alive(p)) {
<<<<<<< HEAD
		struct task_struct *tracer = ptrace_parent(p);
=======
<<<<<<< HEAD
Exemplo n.º 20
0
static void post_fork(int childno)
{
	pid_t pid;

	pid = shm->syscall[childno].retval;
	if (pid == 0) {
		// child
		sleep(1);
		_exit(EXIT_SUCCESS);
	} else {
		__unused__ int ret;

		while (pid_alive(pid)) {
			int status;
			ret = waitpid(pid, &status, WUNTRACED | WCONTINUED | WNOHANG);
		}
	}
}
Exemplo n.º 21
0
int monitor_fn(void* unused)
{
        tm->target_task = get_pid_task(tm->target_pid, PIDTYPE_PID);
        
        while(tm->target_task && pid_alive(tm->target_task)
              && !kthread_should_stop()){
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(HZ);
                pr_info("taskmonitor: pid %d\tusr %d\tsys %d\n", target,
                        (int)tm->target_task->utime,
                        (int)tm->target_task->stime);
        }

        if(tm->target_task)
                put_task_struct(tm->target_task);
        
	pr_warn("monitor_fn: target task is no longer alive !\n");
        
        return 0;
}
Exemplo n.º 22
0
void lock(lock_t *_lock)
{
	while (_lock->lock == LOCKED) {
		_lock->contention++;
		usleep(1);
		if (_lock->contention > STEAL_THRESHOLD) {
			pid_t pid = _lock->owner;

			if (pid_alive(pid) == FALSE) {
				output(0, "[%d] more than %d attempts to get lock. pid %d looks dead, stealing.\n",
					getpid(), STEAL_THRESHOLD, pid);
				goto steal;
			}
		}
	}

steal:
	_lock->contention = 0;
	_lock->lock = LOCKED;
	_lock->owner = getpid();
}
Exemplo n.º 23
0
/* Used by wait */
static void wait_checker(struct work_struct *w)
{
  struct delayed_work * w_del;
  struct wait_struct * w_stru;
  int i;

  w_del = to_delayed_work(w);
  w_stru = container_of(w_del, struct wait_struct, w_delayed);

  wake_up_interruptible(&waiter);

  for (i = 0; i < w_stru->w_size; i++) {
    if (!pid_alive(w_stru->w_pids[i])) {
      w_stru->w_is_finished = i;
      wake_up_interruptible(&waiter);
      return;
    }
  }

  /* On relance la boucle */
  queue_delayed_work(syndicate, &(wOs->w_dw), TICKS_DELAY);
}
Exemplo n.º 24
0
void dump_childnos(void)
{
	unsigned int i, j = 0;
	char string[512], *sptr = string;

	sptr += sprintf(sptr, "## pids: (%u active)\n", shm->running_childs);

	for (i = 0; i < max_children; i += 8) {
		sptr += sprintf(sptr, "%u-%u: ", i, i + 7);
		for (j = 0; j < 8; j++) {
			struct childdata *child;

			if (i + j > max_children)
				break;

			child = shm->children[i + j];

			if (pids[child->num] == EMPTY_PIDSLOT) {
				sptr += sprintf(sptr, "[empty] ");
			} else {
				pid_t pid = pids[child->num];
				if (pid_is_valid(pid) == FALSE)
					sptr += sprintf(sptr, "%s", ANSI_RED);

				if (pid_alive(pid) == FALSE)
					sptr += sprintf(sptr, "%s", ANSI_RED);

				sptr += sprintf(sptr, "%u %s", pid, ANSI_RESET);
			}
		}
		sptr += sprintf(sptr, "\n");
		*sptr = '\0';
		outputerr("%s", string);
		sptr = string;
	}
}
Exemplo n.º 25
0
static void fork_children(void)
{
	int pidslot;
	static char childname[17];

	/* Generate children*/

	while (shm->running_childs < shm->max_children) {
		int pid = 0;

		/* Find a space for it in the pid map */
		pidslot = find_pid_slot(EMPTY_PIDSLOT);
		if (pidslot == PIDSLOT_NOT_FOUND) {
			printf("[%d] ## Pid map was full!\n", getpid());
			dump_pid_slots();
			exit(EXIT_FAILURE);
		}

		(void)alarm(0);
		fflush(stdout);
		pid = fork();
		if (pid != 0)
			shm->pids[pidslot] = pid;
		else {
			/* Child process. */
			int ret = 0;

			mask_signals_child();

			memset(childname, 0, sizeof(childname));
			sprintf(childname, "trinity-child%d", pidslot);
			prctl(PR_SET_NAME, (unsigned long) &childname);

			oom_score_adj(500);

			/* Wait for parent to set our pidslot */
			while (shm->pids[pidslot] != getpid()) {
				/* Make sure parent is actually alive to wait for us. */
				ret = pid_alive(shm->parentpid);
				if (ret != 0) {
					shm->exit_reason = EXIT_SHM_CORRUPTION;
					printf("[%d] " BUGTXT "parent (%d) went away!\n", getpid(), shm->parentpid);
					sleep(20000);
				}
			}

			init_child(pidslot);

			ret = child_process(pidslot);

			output(1, "child %d exiting\n", getpid());

			_exit(ret);
		}
		shm->running_childs++;
		debugf("[%d] Created child %d in pidslot %d [total:%d/%d]\n",
			getpid(), shm->pids[pidslot], pidslot,
			shm->running_childs, shm->max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	debugf("[%d] created enough children\n", getpid());
}
Exemplo n.º 26
0
/* main tests */
int main (int argc, char **argv, char **env) {
    argc = argc; argv = argv; env  = env;
    int status, chld, rc;
    int tests = 125;
    int rrc;
    char cmd[150];
    char *result, *error, *message, *output;
    plan(tests);

    mod_gm_opt = malloc(sizeof(mod_gm_opt_t));
    set_default_options(mod_gm_opt);

#ifdef EMBEDDEDPERL
    char p1[150];
    snprintf(p1, 150, "--p1_file=worker/mod_gearman_p1.pl");
    parse_args_line(mod_gm_opt, p1, 0);
    init_embedded_perl(env);
#endif

    char options[150];
    snprintf(options, 150, "--server=127.0.0.1:%d", GEARMAND_TEST_PORT);
    ok(parse_args_line(mod_gm_opt, options, 0) == 0, "parse_args_line()");
    mod_gm_opt->debug_level = GM_LOG_ERROR;

    worker_logfile = my_tmpfile();
    if(!ok(worker_logfile != NULL, "created temp logile: %s", worker_logfile)) {
        diag("could not create temp logfile");
        exit( EXIT_FAILURE );
    }

    /* first fire up a gearmand server and one worker */
    start_gearmand((void*)NULL);
    sleep(2);
    start_worker((void*)NULL);
    sleep(2);

    /* wait one second and catch died procs */
    while((chld = waitpid(-1, &status, WNOHANG)) != -1 && chld > 0) {
        diag( "waitpid() %d exited with %d\n", chld, status);
        status = 0;
    }

    if(!ok(gearmand_pid > 0, "'gearmand started with port %d and pid: %d", GEARMAND_TEST_PORT, gearmand_pid)) {
        diag("make sure gearmand is in your PATH. Common locations are /usr/sbin or /usr/local/sbin");
        exit( EXIT_FAILURE );
    }
    if(!ok(pid_alive(gearmand_pid) == TRUE, "gearmand alive")) {
        check_logfile("/tmp/gearmand.log", 3);
        kill(gearmand_pid, SIGTERM);
        kill(worker_pid, SIGTERM);
        exit( EXIT_FAILURE );
    }
    if(!ok(worker_pid > 0, "worker started with pid: %d", worker_pid))
        diag("could not start worker");
    if(!ok(pid_alive(worker_pid) == TRUE, "worker alive")) {
        check_logfile(worker_logfile, 3);
        kill(gearmand_pid, SIGTERM);
        kill(worker_pid, SIGTERM);
        exit( EXIT_FAILURE );
    }

    skip(gearmand_pid <= 0 || worker_pid <= 0,
               tests-3,             /* Number of tests to skip */
               "Skipping all tests, no need to go on without gearmand or worker");

    /* create server / clients */
    mod_gm_opt->transportmode = GM_ENCODE_ONLY;
    create_modules();

    /* send big job */
    send_big_jobs(GM_ENCODE_ONLY);
    //diag_queues();
    wait_for_empty_queue("eventhandler", 20);
    wait_for_empty_queue("service", 20);
    //diag_queues();
    do_result_work(1);
    //diag_queues();
    wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5);

    /*****************************************
     * test check
     */
    //diag_queues();
    test_servicecheck(GM_ENCODE_ONLY, "./t/crit.pl");
    //diag_queues();
    wait_for_empty_queue("eventhandler", 20);
    wait_for_empty_queue("service", 5);
    //diag_queues();
    do_result_work(1);
    //diag_queues();
    wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5);
    //diag_queues();
    like(last_result, "test plugin CRITICAL", "stdout output from ./t/crit.pl");
    like(last_result, "some errors on stderr", "stderr output from ./t/crit.pl");

    /*****************************************
     * test check2
     */
    //diag_queues();
    test_servicecheck(GM_ENCODE_ONLY, "./t/both");
    //diag_queues();
    wait_for_empty_queue("eventhandler", 20);
    wait_for_empty_queue("service", 5);
    //diag_queues();
    do_result_work(1);
    //diag_queues();
    wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5);
    like(last_result, "stdout output", "stdout output from ./t/both");
    like(last_result, "stderr output", "stderr output from ./t/both");

    /* try to send some data with base64 only */
    //diag_queues();
    test_eventhandler(GM_ENCODE_ONLY);
    //diag_queues();
    test_servicecheck(GM_ENCODE_ONLY, NULL);
    //diag_queues();
    wait_for_empty_queue("eventhandler", 20);
    wait_for_empty_queue("service", 5);
    //diag_queues();
    do_result_work(1);
    //diag_queues();
    wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5);
    sleep(1);
    kill(worker_pid, SIGTERM);
    waitpid(worker_pid, &status, 0);
    ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status));
    status = 0;
    check_no_worker_running(worker_logfile);
    check_logfile(worker_logfile, 0);

    char * test_keys[] = {
        "12345",
        "test",
        "test key 123",
        "me make you loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong key"
    };

    /* ignore some signals for now */
    signal(SIGTERM, SIG_IGN);

    int i;
    for(i=0;i<4;i++) {
        mod_gm_opt->transportmode = GM_ENCODE_AND_ENCRYPT;
        start_worker((void *)test_keys[i]);

        mod_gm_crypt_init( test_keys[i] );
        ok(1, "initialized with key: %s", test_keys[i]);

        test_eventhandler(GM_ENCODE_AND_ENCRYPT);
        test_servicecheck(GM_ENCODE_AND_ENCRYPT, NULL);
        wait_for_empty_queue("eventhandler", 20);
        wait_for_empty_queue("service", 5);
        do_result_work(1);
        wait_for_empty_queue(GM_DEFAULT_RESULT_QUEUE, 5);
        sleep(1);

        kill(worker_pid, SIGTERM);
        waitpid(worker_pid, &status, 0);
        ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status));
        status = 0;
        check_no_worker_running(worker_logfile);
        check_logfile(worker_logfile, 0);
    }

    /*****************************************
     * send_gearman
     */
    snprintf(cmd, 150, "./send_gearman --server=127.0.0.1:%d --key=testtest --host=test --service=test --message=test --returncode=0", GEARMAND_TEST_PORT);
    rrc = real_exit_code(run_check(cmd, &result, &error));
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    like(result, "^\\s*$", "output from ./send_gearman");
    free(result);
    free(error);

    /*****************************************
     * send_multi
     */
    snprintf(cmd, 150, "./send_multi --server=127.0.0.1:%d --host=blah < t/data/send_multi.txt", GEARMAND_TEST_PORT);
    rrc = real_exit_code(run_check(cmd, &result, &error));
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    like(result, "send_multi OK: 2 check_multi child checks submitted", "output from ./send_multi");
    free(result);
    free(error);

    /*****************************************
     * check_gearman
     */
    snprintf(cmd, 150, "./check_gearman -H 127.0.0.1:%d -s check -a -q worker_test", GEARMAND_TEST_PORT);
    rrc = real_exit_code(run_check(cmd, &result, &error));
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    like(result, "check_gearman OK - sending background job succeded", "output from ./check_gearman");

    /* cleanup */
    free(result);
    free(error);
    free_client(&client);
    free_worker(&worker);

    /* shutdown gearmand */
    rc = send2gearmandadmin("shutdown\n", "127.0.0.1", GEARMAND_TEST_PORT, &output, &message);
    ok(rc == 0, "rc of send2gearmandadmin %d", rc);
    like(output, "OK", "output contains OK");
    free(message);
    free(output);

    /* wait 5 seconds to shutdown */
    for(i=0;i<=5;i++) {
        waitpid(gearmand_pid, &status, WNOHANG);
        if(pid_alive(gearmand_pid) == FALSE) {
            todo();
            ok(status == 0, "gearmand (%d) exited with: %d", gearmand_pid, real_exit_code(status));
            endtodo;
            break;
        }
        sleep(1);
    }

    if(pid_alive(gearmand_pid) == TRUE) {
        /* kill it the hard way */
        kill(gearmand_pid, SIGTERM);
        waitpid(gearmand_pid, &status, 0);
        ok(status == 0, "gearmand (%d) exited with exit code %d", gearmand_pid, real_exit_code(status));
        status = 0;
        ok(false, "gearmand had to be killed!");
    }
    todo();
    check_logfile("/tmp/gearmand.log", status != 0 ? 2 : 0);
    endtodo;
    status = 0;

    kill(worker_pid, SIGTERM);
    waitpid(worker_pid, &status, 0);
    ok(status == 0, "worker (%d) exited with exit code %d", worker_pid, real_exit_code(status));
    check_no_worker_running(worker_logfile);
    status = 0;

#ifdef EMBEDDEDPERL
    deinit_embedded_perl(0);
#endif

    free(last_result);
    free(worker_logfile);
    endskip;
    mod_gm_free_opt(mod_gm_opt);
    return exit_status();
}
Exemplo n.º 27
0
Arquivo: main.c Projeto: guwu/trinity
static void handle_child(pid_t childpid, int childstatus)
{
	switch (childpid) {
	case 0:
		//debugf("Nothing changed. children:%d\n", shm->running_childs);
		break;

	case -1:
		if (shm->exit_reason != STILL_RUNNING)
			return;

		if (errno == ECHILD) {
			unsigned int i;
			bool seen = FALSE;

			debugf("All children exited!\n");

			for_each_child(i) {
				struct childdata *child;

				child = shm->children[i];

				if (child->pid != EMPTY_PIDSLOT) {
					if (pid_alive(child->pid) == -1) {
						debugf("Removing %d from pidmap\n", child->pid);
						child->pid = EMPTY_PIDSLOT;
						shm->running_childs--;
					} else {
						debugf("%d looks still alive! ignoring.\n", child->pid);
					}
					seen = TRUE;
				}
			}
			if (seen == FALSE)
				shm->running_childs = 0;
			break;
		}
		output(0, "error! (%s)\n", strerror(errno));
		break;

	default:
		debugf("Something happened to pid %d\n", childpid);

		if (WIFEXITED(childstatus)) {

			int childno;

			childno = find_childno(childpid);
			if (childno != CHILD_NOT_FOUND) {
				debugf("Child %d exited after %ld operations.\n",
					childpid, shm->children[childno]->syscall.op_nr);
				reap_child(childpid);
			}
			break;

		} else if (WIFSIGNALED(childstatus)) {
			handle_childsig(childpid, childstatus, FALSE);
		} else if (WIFSTOPPED(childstatus)) {
			handle_childsig(childpid, childstatus, TRUE);
		} else if (WIFCONTINUED(childstatus)) {
			break;
		} else {
			output(0, "erk, wtf\n");
		}
	}
Exemplo n.º 28
0
static void fork_children(void)
{
	int pidslot;
	static char childname[17];

	/* Generate children*/

	while (shm->running_childs < shm->max_children) {
		int pid = 0;
		int fd;

		if (shm->spawn_no_more == TRUE)
			return;

		/* a new child means a new seed, or the new child
		 * will do the same syscalls as the one in the pidslot it's replacing.
		 * (special case startup, or we reseed unnecessarily)
		 */
		if (shm->ready == TRUE)
			reseed();

		/* Find a space for it in the pid map */
		pidslot = find_pid_slot(EMPTY_PIDSLOT);
		if (pidslot == PIDSLOT_NOT_FOUND) {
			outputerr("## Pid map was full!\n");
			dump_pid_slots();
			exit(EXIT_FAILURE);
		}

		if (logging == TRUE) {
			fd = fileno(shm->logfiles[pidslot]);
			if (ftruncate(fd, 0) == 0)
				lseek(fd, 0, SEEK_SET);
		}

		(void)alarm(0);
		fflush(stdout);
		pid = fork();
		if (pid != 0)
			shm->pids[pidslot] = pid;
		else {
			/* Child process. */
			int ret = 0;

			mask_signals_child();

			memset(childname, 0, sizeof(childname));
			sprintf(childname, "trinity-child%d", pidslot);
			prctl(PR_SET_NAME, (unsigned long) &childname);

			oom_score_adj(500);

			/* Wait for parent to set our pidslot */
			while (shm->pids[pidslot] != getpid()) {
				/* Make sure parent is actually alive to wait for us. */
				ret = pid_alive(shm->mainpid);
				if (ret != 0) {
					shm->exit_reason = EXIT_SHM_CORRUPTION;
					outputerr(BUGTXT "parent (%d) went away!\n", shm->mainpid);
					sleep(20000);
				}
			}

			/* Wait for all the children to start up. */
			while (shm->ready == FALSE)
				sleep(1);

			init_child(pidslot);

			ret = child_process(pidslot);

			output(1, "child exiting.\n");

			_exit(ret);
		}
		shm->running_childs++;
		debugf("Created child %d in pidslot %d [total:%d/%d]\n",
			shm->pids[pidslot], pidslot,
			shm->running_childs, shm->max_children);

		if (shm->exit_reason != STILL_RUNNING)
			return;

	}
	shm->ready = TRUE;

	debugf("created enough children\n");
}
Exemplo n.º 29
0
static void handle_child(pid_t childpid, int childstatus)
{
	unsigned int i;
	int slot;

	switch (childpid) {
	case 0:
		//debugf("Nothing changed. children:%d\n", shm->running_childs);
		break;

	case -1:
		if (shm->exit_reason != STILL_RUNNING)
			return;

		if (errno == ECHILD) {
			debugf("All children exited!\n");
			for_each_pidslot(i) {
				if (shm->pids[i] != EMPTY_PIDSLOT) {
					if (pid_alive(shm->pids[i]) == -1) {
						debugf("Removing %d from pidmap\n", shm->pids[i]);
						shm->pids[i] = EMPTY_PIDSLOT;
						shm->running_childs--;
					} else {
						debugf("%d looks still alive! ignoring.\n", shm->pids[i]);
					}
				}
			}
			break;
		}
		output(0, "error! (%s)\n", strerror(errno));
		break;

	default:
		debugf("Something happened to pid %d\n", childpid);

		if (WIFEXITED(childstatus)) {

			slot = find_pid_slot(childpid);
			if (slot == PIDSLOT_NOT_FOUND) {
				/* If we reaped it, it wouldn't show up, so check that. */
				if (shm->last_reaped != childpid) {
					outputerr("## Couldn't find pid slot for %d\n", childpid);
					shm->exit_reason = EXIT_LOST_PID_SLOT;
					dump_pid_slots();
				}
			} else {
				debugf("Child %d exited after %ld syscalls.\n", childpid, shm->child_syscall_count[slot]);
				reap_child(childpid);
			}
			break;

		} else if (WIFSIGNALED(childstatus)) {

			switch (WTERMSIG(childstatus)) {
			case SIGALRM:
				debugf("got a alarm signal from pid %d\n", childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("got a signal from pid %d (%s)\n", childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("** Child got an unhandled signal (%d)\n", WTERMSIG(childstatus));
				break;
			}
			break;

		} else if (WIFSTOPPED(childstatus)) {

			switch (WSTOPSIG(childstatus)) {
			case SIGALRM:
				debugf("got an alarm signal from pid %d\n", childpid);
				break;
			case SIGSTOP:
				debugf("Sending PTRACE_DETACH (and then KILL)\n");
				ptrace(PTRACE_DETACH, childpid, NULL, NULL);
				kill(childpid, SIGKILL);
				reap_child(childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("Child %d was stopped by %s\n", childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("Child %d was stopped by unhandled signal (%s).\n", childpid, strsignal(WSTOPSIG(childstatus)));
				break;
			}
			break;

		} else if (WIFCONTINUED(childstatus)) {
			break;
		} else {
			output(0, "erk, wtf\n");
		}
	}
Exemplo n.º 30
0
Arquivo: array.c Projeto: 020gzh/linux
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
				struct pid *pid, struct task_struct *p)
{
	struct user_namespace *user_ns = seq_user_ns(m);
	struct group_info *group_info;
	int g;
	struct task_struct *tracer;
	const struct cred *cred;
	pid_t ppid, tpid = 0, tgid, ngid;
	unsigned int max_fds = 0;

	rcu_read_lock();
	ppid = pid_alive(p) ?
		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;

	tracer = ptrace_parent(p);
	if (tracer)
		tpid = task_pid_nr_ns(tracer, ns);

	tgid = task_tgid_nr_ns(p, ns);
	ngid = task_numa_group_id(p);
	cred = get_task_cred(p);

	task_lock(p);
	if (p->files)
		max_fds = files_fdtable(p->files)->max_fds;
	task_unlock(p);
	rcu_read_unlock();

	seq_printf(m,
		"State:\t%s\n"
		"Tgid:\t%d\n"
		"Ngid:\t%d\n"
		"Pid:\t%d\n"
		"PPid:\t%d\n"
		"TracerPid:\t%d\n"
		"Uid:\t%d\t%d\t%d\t%d\n"
		"Gid:\t%d\t%d\t%d\t%d\n"
		"FDSize:\t%d\nGroups:\t",
		get_task_state(p),
		tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid,
		from_kuid_munged(user_ns, cred->uid),
		from_kuid_munged(user_ns, cred->euid),
		from_kuid_munged(user_ns, cred->suid),
		from_kuid_munged(user_ns, cred->fsuid),
		from_kgid_munged(user_ns, cred->gid),
		from_kgid_munged(user_ns, cred->egid),
		from_kgid_munged(user_ns, cred->sgid),
		from_kgid_munged(user_ns, cred->fsgid),
		max_fds);

	group_info = cred->group_info;
	for (g = 0; g < group_info->ngroups; g++)
		seq_printf(m, "%d ",
			   from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
	put_cred(cred);

#ifdef CONFIG_PID_NS
	seq_puts(m, "\nNStgid:");
	for (g = ns->level; g <= pid->level; g++)
		seq_printf(m, "\t%d",
			task_tgid_nr_ns(p, pid->numbers[g].ns));
	seq_puts(m, "\nNSpid:");
	for (g = ns->level; g <= pid->level; g++)
		seq_printf(m, "\t%d",
			task_pid_nr_ns(p, pid->numbers[g].ns));
	seq_puts(m, "\nNSpgid:");
	for (g = ns->level; g <= pid->level; g++)
		seq_printf(m, "\t%d",
			task_pgrp_nr_ns(p, pid->numbers[g].ns));
	seq_puts(m, "\nNSsid:");
	for (g = ns->level; g <= pid->level; g++)
		seq_printf(m, "\t%d",
			task_session_nr_ns(p, pid->numbers[g].ns));
#endif
	seq_putc(m, '\n');
}