Understanding sleeping mechanism in Linux Kernel

The students of INFO-0940 were asked to remove a task from it’s current scheduler class when calling a new syscall and put it back when we call again that syscall. The question is : what to do if the task is currently sleeping? Cause the timer will expire at one moment and maybe put back the state to TASK_RUNNING and run the task which should haven’t been able to run again. So either it expires after the processus is back in its previous scheduler, and that’s okay as it will reset it in a runnable state. Or it expires while it’s still removed, and that’s a problem as it will put it back in its previous state (or not, depending on how the syscall is implemented).
Warning : this post is just the result of a quick look. More to give you some ideas and basis for understanding the sleeping mechanism.

 

So we should try to understand how sleep works.

 

Let’s look at the nanosleep syscall (which is called when you user sleep() or usleep() functions in C).

SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
		struct timespec __user *, rmtp)
{
	struct timespec tu;

	if (copy_from_user(&tu, rqtp, sizeof(tu)))
		return -EFAULT;

	if (!timespec_valid(&tu))
		return -EINVAL;

	return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
}

It copies the userspace data, check that the time is valid and call hrtimer_nanosleep.

long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
		       const enum hrtimer_mode mode, const clockid_t clockid)
{
	struct restart_block *restart;
	struct hrtimer_sleeper t;
	int ret = 0;
	unsigned long slack;

	slack = current->timer_slack_ns;
	if (rt_task(current))
		slack = 0;

	hrtimer_init_on_stack(&t.timer, clockid, mode);
	hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
	if (do_nanosleep(&t, mode))
		goto out;

	/* Absolute timers do not update the rmtp value and restart: */
	if (mode == HRTIMER_MODE_ABS) {
		ret = -ERESTARTNOHAND;
		goto out;
	}

	if (rmtp) {
		ret = update_rmtp(&t.timer, rmtp);
		if (ret <= 0)
			goto out;
	}

	restart = &current_thread_info()->restart_block;
	restart->fn = hrtimer_nanosleep_restart;
	restart->nanosleep.clockid = t.timer.base->clockid;
	restart->nanosleep.rmtp = rmtp;
	restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);

	ret = -ERESTART_RESTARTBLOCK;
out:
	destroy_hrtimer_on_stack(&t.timer);
	return ret;
}

It initialize a timer and call do_nanosleep giving it the timer. After do_nanosleep it will destroy/free the timer structure.

static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
{
	hrtimer_init_sleeper(t, current);

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		hrtimer_start_expires(&t->timer, mode);
		if (!hrtimer_active(&t->timer))
			t->task = NULL;

		if (likely(t->task))
			schedule();

		hrtimer_cancel(&t->timer);
		mode = HRTIMER_MODE_ABS;

	} while (t->task && !signal_pending(current));

	__set_current_state(TASK_RUNNING);

	return t->task == NULL;
}

This is the interesting part.

 

The first thing done is calling hrtimer_init_sleeper(); which will set parameters of the timer to call the function hrtimer_wakeup when the timer expires, and specify the task to wakeup at that time. hrtimer_wakeup will simply set the task to NULL and call wake_up_process() on that task. We’ll come back to wake_up_process(task) later.

 

We see that after that the state is changed to TASK_INTERRUPTIBLE. Then it starts the timer strictly speaking, and go in schedule().

 

Remember that schedule(), before scheduling a new task, will test the state of the current (which is now “previous”) task, and if the state is not TASK_RUNNING, it will remove that task from its runqueue (and that is the case as it is in the TASK_INTERRUPTIBLE state).

 

Schedule() goes on and start scheduling another task, if there is not, it will run the “idle” task.

 

At some point, the timer will expire. The timer rely on an hardware timer which will cause an interrupt, leaving any current task to process the interrupt handler (this is not the schedule() handler and so on !). The interrupt handler for the hardware timer is  hrtimer_interrupt() which will run hrtimer_wakeup() for all expired timer. As said before, outr timer for the sleeping mechanism will set the timer task as NULL, and call wake_up_process(). But that functions just put back the process in the runqueue and set its state to TASK_RUNNING, not actually scheduling it. The interrupt handler will finish and the CPU will go back to it’s currently running process (maybe the idle process, running the cpu_idle() function). 

 

That currently running process will eventually finish its processing or be preempted (the normal scheduling mechanism), and the process which was sleeping will re-run again when it will be picked again by pick_next_task().

 

But where will this process restart? After the sleep() or usleep() call? No ! Where it was… in the nanosleep syscall. What does the syscall do after its call to schedule()? Put the state back to TASK_RUNNING and effectively running. That seems obvious as we said before that the syscall is taking care of destroying the timer structure, so it should not restart after the syscall.

 

Note that I skipped the part where do_nanosleep() is looping and so on… I tried usleep(1) and sleep(1), and the loop never happend. I suspect it’s for very long timers, the kernel would’nt launch a timer of 1 hour long… But it’s just a guess.

 

SourceForts Console commands

SourceForts is really a great mod for Half-Life 2 multiplayer, featuring a construction phase with blocks and panels before a combat phase. But the wiki has died a long time ago, and I decided to copy a save of the console commands here, as it’s not findable anymore.

Common Commands

Phase Limits

  • addtime [integer] Adds time (in seconds) to the current phase (can remove time too if integer is negative)
  • sf_build_long_length Length of the long Build Phase in seconds. Default 600
  • sf_build_short_length Length of the short build phase in seconds. Default 240
  • sf_combat_length Length of Combat Phase in seconds. Default 600
  • togglephase Changes the phase (either from build to fight or vice versa)

Match Limits

  • sf_roundlimit Number of rounds (cycles of Build / Combat) a map is played for. Default 4
  • sf_scorelimit [integer] Amount of points for a team to win the game. Default 1000
  • map_restart cmd – Completely restarts game, all scores returned to zero and all blocks removed.

Team Limits

  • sf_forcebalance Default : 1 – Force team balancing on connect. While on, you can only join the team with the least players.
  • sf_team_blocklimit [integer] Sets the blocklimit for both teams
  • sf_team_autoassign [0/1] Setting of 1 forces joining players to join smallest team

Blocks

  • sf_block_damage_multiplier Default : 3 – Multiplier of damage dealt to blocks by weapons. Higher number = blocks are easier to destroy.
  • sf_block_extra_force Default : 10 – Physics damage multiplier if hit by a block in combat.
  • sf_block_health Default : 6000 – Block damage health
  • sf_block_unfreeze_health Default : 1250 – Block unfreeze health, basically sets the time it takes to unfreeze a block.
  • sf_combat_freeze_friendly Default : 6 – Time in seconds to freeze a friendly block
  • sf_combat_unfreeze_enemy Default : 12 – Time in seconds to unfreeze an enemy block
  • sf_combat_unfreeze_friendly Default : 4 – Time in seconds to unfreeze a friendly block.
  • sf_freeze_continue_distance_combat Default : 16 – How far, in units, you have to be from a block to freeze it.
  • sf_freeze_continue_player_move_distance_combat Default : 16 – How far, in units, you can move from a block while freezing it without stopping.
  • sf_freeze_distance_build Default : 600 – How far, in units, you can freeze/unfreeze blocks in build phase
  • sf_freeze_starting_distance_combat Default : 128
  • sf_repair_delay Default : 0 – How long, after holding fire, it takes for you to start repairing a block (obsolete)
  • sf_repair_distance Default : 96 – How far you can be from a block to repair it.
  • sf_repair_increment Default : 45 – How many HP you return to a block while repairing

Class Settings

  • sf_armor_builder Default : 20Engineer armour
  • sf_armor_heavysoldier Default : 75Soldier armour
  • sf_armor_rocketeer Default : 40Rocketeer armour
  • sf_armor_scout Default : 15Scout armour
  • sf_armor_sniper Default : 0Sniper armour
  • sf_health_builder Default : 80 – Engineers health
  • sf_health_heavysoldier Default : 100 – Soldiers health
  • sf_health_rocketeer Default : 100 – Rocketeers health
  • sf_health_scout Default : 100 – Scouts health
  • sf_health_sniper Default : 75 – Snipers health
  • sf_player_limits_enabled Default : 1 – Enables/disables percentage based class limiting
  • sf_player_limits_engineer_percentage Default : 75 – Percentage limit for engineer
  • sf_player_limits_rocketeer_percentage Default : 60 – Percentage limit for rocketeer
  • sf_player_limits_scout_percentage Default : 100 – Percentage limit for scout
  • sf_player_limits_sniper_percentage Default : 25 – Percentage limit for sniper
  • sf_player_limits_soldier_percentage Default : 66 – Percentage limit for soldier
  • sf_run_builder Default : 0
  • sf_run_heavysoldier Default : 0
  • sf_run_rocketeer Default : 1
  • sf_run_scout Default : 1
  • sf_run_sniper Default : 0
  • sf_sprint_builder Default : 1
  • sf_sprint_drain_builder Default : 1
  • sf_sprint_drain_heavysoldier Default : 1
  • sf_sprint_drain_rocketeer Default : 1
  • sf_sprint_drain_scout Default : 0
  • sf_sprint_drain_sniper Default : 1
  • sf_sprint_heavysoldier Default : 1
  • sf_sprint_rocketeer Default : 1
  • sf_sprint_scout Default : 1
  • sf_sprint_sniper Default : 1

Flag Settings

  • sf_flag_drop_distance Default : 50 – How far away from you the flag is dropped if you drop it.
  • sf_flag_returntime Default : 30 – Time in seconds for the flag to return itself to its base.
  • sf_flag_x Default : 0 – Unknown
  • sf_flag_y Default : 0 – Unknown
  • sf_flag_z Default : 100 – Unknown

League Commands

  • league_flip cmd – Flips teams over, while maintaining scores.
  • league_flipscores cmd – Flips scores only
  • league_flipteams cmd – Flips teams only

Map Elements

  • sf_charger_armor_increment Default : 2 – Suit charger speed
  • sf_charger_health_increment Default : 2 – Health charger speed

Undocumented / Beta Commands

  • sf_ar2_range1_damage Default : 0 – Beta cvars used to test the dissipating power/range ratios on the AR2.
  • sf_ar2_range1_distance Default : 1000 – See above.
  • sf_ar2_range2_damage Default : 0 – See above.
  • sf_ar2_range2_distance Default : 2000 – See above.
  • sf_deny_respawn Default : 0 – Unknown, probably beta command.

Weapon Settings

  • sf_damage_crossbow Default : 100Crossbow damage
  • sf_damage_rpg Default : 125RPG damage (if hit directly. Damage dissipates the further from explosion you are)
  • sf_grenade_throw_force_multiplier Default : 800 – Controls range of grenades

Half Life 2 Deathmatch Commands

For a more complete list of console commands for Half-Life 2, see the HL2World wiki. Some of the most common and useful commands are shown below.

Useful Commands

  • sv_cheats Default : 0 – Server setting that turns cheat mode on or off.
  • sv_lan Default : 0Server setting, value of 0 is an internet server, 1 is a LAN server.
  • ip Default : localhostServer setting, needs to be changed to global IP address on servers utilizing routed Internet connections.

Using Cheat Codes

The following commands require that the server have cheats enabled.

  • impulse 101 cmd – Gives you one of every weapon. Needs cheats
  • impulse 200 cmd – Removes your HUD good for taking screenshots. Needs cheats
  • impulse 203 cmd – Removes an entity, used for removing SourceForts blocks. Needs cheats Warning: Using this on players will crash your server

Spawning Blocks

If the cheat mode is turned on players can give themselves blocks, without using a blockspawner. This adds to the blueteams block limit, so it is considered a cheat.

*give prop_block_2d_1x2
*give prop_block_2d_2x3
*give prop_block_2d_1x5
*give prop_block_3d_1x2
*give prop_block_3d_1x1

Home server : auto-shutdown if no other computers are running

I wanted to shutdown my linux home media server if there is no running computer on my network. So I wrote this little programs which reads all known ips from DHCP configuration and lease files and send a ping to them. If the ping respond, one PC of my LAN is up… To re-start the computer in the morning, I use the BIOS RTC alarm (the thing you have by pressing F1 or ESC on reboot). You could also add a script/a program on each of your computers to send the magic packet to your home server to wake it by lan (see “wake on lan” on google). This script can take any command. But if you want to do shutdown like proposed in the title, you can use : [code]sudo ./autoshut “poweroff” 10.0.0.1[/code] Where 10.0.0.1 is your local IP adress. To compile the program, simply use (after saving the code as “autoshut.c”) : [code]gcc -o autoshut autoshut.c[/code] In my case, I wanted to launch the command only after midnight, so I used cron. Cron will launch that command every 5 minutes from midnight to eight o’clock. So if I stay up late, my server won’t shutdown if my own computer is not down too. That’s the whole purpose. The line in my crontab : [code]0,10,20,30,40,50 1,2,3,4,5,6,7 * * * root /home/tom/autoshut/autoshut “poweroff” 10.0.0.1[/code] Why do all that ? Energy consumption… [code]#include <stdio.h> #include <stdlib.h> #include <regex.h> #include <string.h> #define LEASE_FILE “/var/lib/dhcp/dhcpd.leases” #define DHCP_CONFIG_FILE “/etc/dhcp/dhcpd.conf” int in_array(char** ar, char* str) { int i = 0; while (ar[i] != NULL) { if (strcmp(ar[i],str) == 0) return 1; i++; } return 0; } char* extractIP (char* filename, char** list, int* listNum) { FILE *pfile; pfile = fopen(filename, “rb”); if(pfile == NULL){ printf(“Sorry, can’t open %s\n”, filename); return ‘\0’; } regex_t reg; int err = regcomp (&reg, “(10\\.[0-1]\\.0\\.([1-9]|[0-9]{2,3}))”, REG_EXTENDED); if (err != 0) { printf(“ERREUR\n”); return ‘\0’; } char ligne[255]; while(!feof(pfile)) { fgets(ligne, 254 ,pfile); int match; size_t nmatch = 0; regmatch_t *pmatch = NULL; nmatch = reg.re_nsub; pmatch = malloc (sizeof (*pmatch) * nmatch); match = regexec (&reg, ligne, nmatch, pmatch, 0); if (match == 0) { char *ip = NULL; int start = pmatch->rm_so; int end = pmatch->rm_eo; size_t size = end – start; char* str = malloc(sizeof(char) * 15); strncpy (str, &ligne[start], size); str[size] = ‘\0’; if (!in_array(list, str)) { list[*listNum] = str; printf(“%s\n”, str); (*listNum)++; } } } fclose(pfile); regfree(&reg); } int ping(char* address) { char cmd[30] = “ping -W 1 -q -c 1 “; strcat(cmd,address); int ret=system(cmd); printf(“\nResultat : %d\n\n”,ret); return !ret; } /* TODO : maybe an option? int checkCableStatus(const char* interface) { /sys/class/net/eth0/carrier }*/ int main(int argc, char** argv) { if (argc <= 2) { printf(“Usage : %s Command Local-IP [Local-IP-2]\n\tCommand : a command to execute if ping does not work\n\tLocal-IP : Ip to ignore\n\tLocal-IP-2 : Optional second ip to ignore”,argv[0]); return -1; } int listNum = 0; char** list = malloc(sizeof(char*) * 255); extractIP(DHCP_CONFIG_FILE, list, &listNum); extractIP(LEASE_FILE, list, &listNum); int i = 0; while (list[i] != NULL) { if (strcmp(list[i],argv[2])!=0 && (argc==3 ||strcmp(list[i],argv[3])!=0)) { if (ping (list[i])) { printf(“%s responded. Command aborted !\n”,list[i]); return EXIT_SUCCESS; } } i++; } system(argv[1]); return EXIT_SUCCESS; }[/code]

Can a task have multiple states?

A little correction about what I said in class… I said that technically, a task could have multiple states because it’s a bitmask but not in practice. It seems that was before that, and searching for TASK_KILLABLE in the linux kernel code (and not sched.c only, that was my mistake), you’ll find for example in timer.c :

 

[code]__set_current_state(TASK_KILLABLE);[/code]

 

And TASK_KILLABLE is a combinaison of two states… So it’s not just used for convenient “multiple test at once”.

Update about the assignment #3

As asked in class, I forgot to precise two things :

The scheduler class has to be placed between sched_stop and sched_rt. If multiple tasks have greenlights available, you’ll pick the task with the most greenlights left. If their number of greenlights is equal, you’re free to choose any task.

 

Note that the printed version has the wrong submission date 😉

Standalone version of chrt

This is a modification of the program chrt (used to change the policy of a process) which has no external dependencies. It can be compiled using “gcc -o chrt chrt.c”.

 

[code]/*
 * chrt.c - chrt
 * Command-line utility for manipulating a task's real-time attributes 
 *
 * Robert Love <rml@tech9.net>
 * 27-Apr-2002: initial version
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, v2, as
 * published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Copyright (C) 2004 Robert Love
 */

#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <err.h>

#define PACKAGE_STRING "modified for greentask"
#define FALSE 0
#define TRUE 1

/* the SCHED_BATCH is supported since Linux 2.6.16
 *  -- temporary workaround for people with old glibc headers
 */
#if defined (__linux__) && !defined(SCHED_BATCH)
# define SCHED_BATCH 3
#endif

/* the SCHED_IDLE is supported since Linux 2.6.23
 * commit id 0e6aca43e08a62a48d6770e9a159dbec167bf4c6
 * -- temporary workaround for people with old glibc headers
 */
#if defined (__linux__) && !defined(SCHED_IDLE)
# define SCHED_IDLE 5
#endif

#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
#define SCHED_RESET_ON_FORK 0x40000000
#endif

#define SCHED_GREEN 6

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

char* _(char* s) {
	return s;
}

long strtol_or_err(const char *str, const char *errmesg)
{
	long num;
	char *end = NULL;

	if (str != NULL && *str != '\0') {
		errno = 0;
		num = strtol(str, &end, 10);
		if (errno == 0 && str != end && end != NULL && *end == '\0')
			return num;
	}
	error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
	return 0;
}

static void __attribute__((__noreturn__)) show_usage(int rc)
{
	FILE *out = rc == EXIT_SUCCESS ? stdout : stderr;

	fprintf(out, _(
	"\nchrt - manipulate real-time attributes of a process\n"
	"\nSet policy:\n"
	"  chrt [options] <policy> <priority> {<pid> | <command> [<arg> ...]}\n"
	"\nGet policy:\n"
	"  chrt [options] {<pid> | <command> [<arg> ...]}\n"));

	fprintf(out, _(
	"\nScheduling policies:\n"
	"  -b | --batch         set policy to SCHED_BATCH\n"
	"  -f | --fifo          set policy to SCHED_FIFO\n"
	"  -i | --idle          set policy to SCHED_IDLE\n"
	"  -o | --other         set policy to SCHED_OTHER\n"
	"  -g | --green         set policy to SCHED_GREEN\n"
	"  -r | --rr            set policy to SCHED_RR (default)\n"));

#ifdef SCHED_RESET_ON_FORK
	fprintf(out, _(
	"\nScheduling flags:\n"
	"  -R | --reset-on-fork set SCHED_RESET_ON_FORK for FIFO or RR\n"));
#endif
	fprintf(out, _(
	"\nOptions:\n"
	"  -h | --help          display this help\n"
	"  -m | --max           show min and max valid priorities\n"
	"  -p | --pid           operate on existing given pid\n"
	"  -v | --verbose       display status information\n"
	"  -V | --version       output version information\n\n"));

	exit(rc);
}

static void show_rt_info(pid_t pid, int isnew)
{
	struct sched_param sp;
	int policy;

	/* don't display "pid 0" as that is confusing */
	if (!pid)
		pid = getpid();

	policy = sched_getscheduler(pid);
	if (policy == -1)
		err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);

	if (isnew)
		printf(_("pid %d's new scheduling policy: "), pid);
	else
		printf(_("pid %d's current scheduling policy: "), pid);

	switch (policy) {
	case SCHED_OTHER:
		printf("SCHED_OTHER\n");
		break;
	case SCHED_FIFO:
		printf("SCHED_FIFO\n");
		break;
#ifdef SCHED_RESET_ON_FORK
	case SCHED_FIFO|SCHED_RESET_ON_FORK:
		printf("SCHED_FIFO|SCHED_RESET_ON_FORK\n");
		break;
#endif
#ifdef SCHED_IDLE
	case SCHED_IDLE:
		printf("SCHED_IDLE\n");
		break;
#endif
#ifdef SCHED_IDLE
	case SCHED_GREEN:
		printf("SCHED_GREEN\n");
		break;
#endif
	case SCHED_RR:
		printf("SCHED_RR\n");
		break;
#ifdef SCHED_RESET_ON_FORK
	case SCHED_RR|SCHED_RESET_ON_FORK:
		printf("SCHED_RR|SCHED_RESET_ON_FORK\n");
		break;
#endif
#ifdef SCHED_BATCH
	case SCHED_BATCH:
		printf("SCHED_BATCH\n");
		break;
#endif
	default:
		printf(_("unknown\n"));
	}

	if (sched_getparam(pid, &sp))
		err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);

	if (isnew)
		printf(_("pid %d's new scheduling priority: %d\n"),
		       pid, sp.sched_priority);
	else
		printf(_("pid %d's current scheduling priority: %d\n"),
		       pid, sp.sched_priority);
}

static void show_min_max(void)
{
	int i;
	int policies[] = { SCHED_OTHER, SCHED_FIFO, SCHED_RR,
#ifdef SCHED_BATCH
			   SCHED_BATCH,
#endif
#ifdef SCHED_IDLE
			   SCHED_IDLE,
#endif
#ifdef SCHED_GREEN
			   SCHED_GREEN,
#endif
			 };
	const char *names[] = { "OTHER", "FIFO", "RR",
#ifdef SCHED_BATCH
				"BATCH",
#endif
#ifdef SCHED_IDLE
				"IDLE",
#endif
#ifdef SCHED_GREEN
				"GREEN",
#endif
			      };

	for (i = 0; i < ARRAY_SIZE(policies); i++) {
		int max = sched_get_priority_max(policies[i]);
		int min = sched_get_priority_min(policies[i]);

		if (max >= 0 && min >= 0)
			printf(_("SCHED_%s min/max priority\t: %d/%d\n"),
					names[i], min, max);
		else
			printf(_("SCHED_%s not supported?\n"), names[i]);
	}
}

int main(int argc, char *argv[])
{
	int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0;
	struct sched_param sp;
	pid_t pid = -1;

	static const struct option longopts[] = {
		{ "batch",	0, NULL, 'b' },
		{ "fifo",	0, NULL, 'f' },
		{ "idle",	0, NULL, 'i' },
		{ "pid",	0, NULL, 'p' },
		{ "help",	0, NULL, 'h' },
		{ "max",        0, NULL, 'm' },
		{ "other",	0, NULL, 'o' },
		{ "rr",		0, NULL, 'r' },
		{ "green",		0, NULL, 'g' },
		{ "reset-on-fork", 0, NULL, 'R' },
		{ "verbose",	0, NULL, 'v' },
		{ "version",	0, NULL, 'V' },
		{ NULL,		0, NULL, 0 }
	};

	while((i = getopt_long(argc, argv, "+bfgiphmoRrvV", longopts, NULL)) != -1)
	{
		int ret = EXIT_FAILURE;

		switch (i) {
		case 'b':
#ifdef SCHED_BATCH
			policy = SCHED_BATCH;
#endif
			break;
		case 'f':
			policy = SCHED_FIFO;
			break;
#ifdef SCHED_RESET_ON_FORK
		case 'R':
			policy_flag |= SCHED_RESET_ON_FORK;
			break;
#endif
		case 'i':
#ifdef SCHED_IDLE
			policy = SCHED_IDLE;
#endif
			break;
		case 'g':
#ifdef SCHED_GREEN
			policy = SCHED_GREEN;
#endif
			break;
		case 'm':
			show_min_max();
			return 0;
		case 'o':
			policy = SCHED_OTHER;
			break;
		case 'p':
			errno = 0;
			pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
			break;
		case 'r':
			policy = SCHED_RR;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			printf("chrt (%s)\n", PACKAGE_STRING);
			return 0;
		case 'h':
			ret = EXIT_SUCCESS;
		default:
			show_usage(ret);
		}
	}

	if (((pid > -1) && argc - optind < 1) || ((pid == -1) && argc - optind < 2))
		show_usage(EXIT_FAILURE);

	if ((pid > -1) && (verbose || argc - optind == 1)) {
		show_rt_info(pid, FALSE);
		if (argc - optind == 1)
			return EXIT_SUCCESS;
	}

	errno = 0;
	priority = strtol_or_err(argv[optind], _("failed to parse priority"));

#ifdef SCHED_RESET_ON_FORK
	/* sanity check */
	if ((policy_flag & SCHED_RESET_ON_FORK) &&
	    !(policy == SCHED_FIFO || policy == SCHED_RR))
		errx(EXIT_FAILURE, _("SCHED_RESET_ON_FORK flag is suppoted for "
				"SCHED_FIFO and SCHED_RR policies only"));
#endif

	policy |= policy_flag;

	if (pid == -1)
		pid = 0;
	sp.sched_priority = priority;
	if (sched_setscheduler(pid, policy, &sp) == -1)
		err(EXIT_FAILURE, _("failed to set pid %d's policy"), pid);

	if (verbose)
		show_rt_info(pid, TRUE);

	if (!pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		printf("FINIIISHED\n");
		perror("execvp");
		err(EXIT_FAILURE, _("failed to execute %s"), argv[0]);
	}

	return EXIT_SUCCESS;
}[/code]

Automatically find all returned e-mails from “Undelivered messages”

If you’ve got your mails under a text format in a folder (like the unix Maildir) you can use this command to extract the e-mails with a 550 return error.

 

cat * | grep --text -Pzoi '([a-z0-9._-]+@[a-z0-9.]+)(?=.*host.*said.*55[0-9])'

 

The first command in the pipe, cat, send all files content to the next command in the pipe : grep. Grep is removing everything except what is an adress, and only if it is followed by “host * said * 55[0-9] ” where * can be everything and [0-9] is a number between 0 and 9. We also use the –text parameter because some mails could contain binary data.

 

As grep give you the mail separated by new line, and an sql command takes a list of strings separated by comma, you can copy the list in gedit or notepad++ and use search->replace to change them in the format ‘mail1’, ‘mail2’, … You have to put “(.*)” in the search field, “‘\1’,” in the replace by field, and select “regular expression”. You then place the result in the parenthesis after IN, in SQL command below :

 

UPDATE contact SET mail='' WHERE mail IN ('bad@hotmail.com', 'error@mail.com')

 

Manual network configuration under ubuntu

This procedure is only with cable, not for wifi

First check that your interface is up with the command “sudo ifconfig” :

lo
If like in this screenshot you do not see an interface named “ethXXX“, you have to start the interface manually.
 
To found which of eth0, eth1, … your network card is, you can type “dmesg | grep eth

dmesg
We see here that the card “Intel Pro/1000” takes the “eth0” interface name. But it’s later renamed to “eth1“.
 
So our interface here is eth1, to bring it up, simply run “sudo ifconfig eth1 up”.
eth1up

You may not have an IP Adress automatically like in this screenshot. If it’s the case, simply type “sudo dhclient eth1” to get one with DHCP.
 
If it doesn’t work, try to directly ping an IP address like google’s dns server 8.8.8.8 with the command “ping 8.8.8.8“. If it works, you probably have a nameserver problem. Simply add the line “nameserver 8.8.8.8” in /etc/resolv.conf

Remove message “Waiting for network configuration…” on ubuntu

On ubuntu, if your system boots without network in failsafe mode, it will wait a long time for network to be available. In many case, this won’t help much…

Moreover, if you’re trying to do things like kernel compiling and for some reason you can’t see the boot log (including this “Waiting for network configuration” message), you’ll have the impression of being stuck with a bad kernel, but in fact it is just waiting 120 seconds…

Just edit the file sudo vi /etc/init/failsafe.conf and remove all “sleep” instructions. The message will be displayed but it won’t wait any time.

To repair you network problems, you might want to check this post and this post.

HDParm

HDParm is a tool to manage your drives. The first section show you how to get informations about your drives, the second tells you how to make them sleep when they aren’t used (and so make power economy). If you’ve got a home server like me with the system on a SSD, with only your big files on the hard drives(s), you’ll want to do this.

 

Get disk informations

You’ve got to use “sudo” to gain super user privilege. Your disk are in the /dev/ folder, named sd* where “*” is a letter. To see the list of disk, one can type use “ls /dev/sd[a-z]“:
debserver % ls /dev/sd[a-z]
/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde

 

To display informations about one disk, you can use “sudo hdparm -i”

 

debserver % sudo hdparm -i /dev/sda
/dev/sda:

Model=WDC WD20EFRX-68EUZN0, FwRev=80.00A80, SerialNo=WD-WCC4M1067803
Config={ HardSect NotMFM HdSw>15uSec SpinMotCtl Fixed DTR>5Mbs FmtGapReq }
RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=0
BuffType=unknown, BuffSize=unknown, MaxMultSect=16, MultSect=16
CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=3907029168
IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}
PIO modes: pio0 pio3 pio4
DMA modes: mdma0 mdma1 mdma2
UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 *udma6
AdvancedPM=no WriteCache=enabled
Drive conforms to: Unspecified: ATA/ATAPI-1,2,3,4,5,6,7

* signifies the current active mode

 

Make a drive sleep after some time

From the manual (man hdparm on the command line):

-S Set the standby (spindown) timeout for the drive. This value is used by the drive to determine how long to wait (with no disk activity) before turning off the spindle motor to save power. Under such circumstances, the drive may take as long as 30 seconds to respond to a subsequent disk access, though most drives are much quicker. The encoding of the timeout value is somewhat peculiar. A value of zero means "timeouts are disabled": the device will not automatically enter standby mode. Values from 1 to 240 specify multiples of 5 seconds, yielding timeouts from 5 seconds to 20 minutes. Values from 241 to 251 specify from 1 to 11 units of 30 minutes, yielding timeouts from 30 minutes to 5.5 hours. A value of 252 signifies a timeout of 21 minutes. A value of 253 sets a vendor-defined timeout period between 8 and 12 hours, and the value 254 is reserved. 255 is interpreted as 21 minutes plus 15 seconds. Note that some older drives may have very different interpretations of these values.

 

So “sudo hdparm -I /dev/sdb | grep level” will show the current spindown value, for Example:

debserver % sudo hdparm -I /dev/sdb | grep level
Advanced power management level: 254

Example:

sudo hdparm -S 25 /dev/sdb = spindown after 25*5 seconds.

sudo hdparm -S 245 /dev/sdb = spindown after (245-240)*30 minutes.

 

If you want to check the state to see if it works :

sudo watch -n 1 "hdparm -C /dev/sdb && hdparm -C /dev/sdc && hdparm -C /dev/sdd && hdparm -C /dev/sde"

 

You can use /etc/hdparm.conf to make it permanent:
/dev/sdb {
spindown_time = 60
}