Posts Tagged ‘łamigłówki’

failing ls ?

2008-02-07 22:58:00 CET | 1 Comment | Tags: , ,

i have this program, which forks-off worker processes, and then runs in them various tasks.

one of the tasks is to execute some command via system(), but since we need to get stdout and stderr (separately), we used ipc::run module.

simple example of such code would be:

#!/usr/bin/perl
use strict;
use Time::HiRes qw( usleep );
use IPC::Run qw( run );
use POSIX ":sys_wait_h";
sub REAPER {
my $child;
while (($child = waitpid(-1,WNOHANG)) > 0) {
}
$SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;
for (1..100) {
my $x = fork;
die "cannot fork?!: $!\n" unless defined $x;
if ($x) {
usleep(10000);
next;
}
my @cmd = qw(ls -lad .);
my ($in, $out, $err);
my $status = run \@cmd, \$in, \$out, \$err or die "ls: $?";
printf ("%u\n", $status);
exit;
}

what it does:

  • defines REAPER function, and sets it as sigchld handler - for details, please check perldoc perlipc. this is basically to avoid creation of zombie processes in case we have long-running parent process, which forks relatively short-lived child-processes.
  • forks off new process
  • after forking, master sleeps for 0.01 second (not to put to much pressure on testing system)
  • child process runs sample command (ls -ald .) via ipc::run, with empty stdin, and catching stdout and stderr.
  • child then exits
  • whole forking/ls-ald. thing is repeated 100 times to show that it’s effect is not random.

what’s wrong? here is output from it on my machine:

=> perl test.pl
ls: -1 at test.pl line 24.
...
...
...

which basically means ls failed - which is far from true, as this ls succeeds, simple check:

=> perl -e 'use IPC::Run qw(run);my @cmd = qw(ls -lad .);my ($in, $out, $err);my $status = run \@cmd, \$in, \$out, \$err or die "ls: $?";printf ("%u\n", $status);'
1

now, the riddle is: why it fails? (yes, i now know the answer, but it took me some time).

while + ssh = ?

2007-09-18 15:48:47 CEST | 3 Comments | Tags: , ,

[ wersja polska poniżej ]

english version

just found this nice brain teaser.

i have this code in bash:

echo -e "1 1\n2 2" | while read A B; do echo "[$A] [$B]“; echo “ZZZ”; done

it will print:

[1] [1]
ZZZ
[2] [2]
ZZZ

which is perfectly valid and sensible.

but if i’ll change the command to:

echo -e "1 1\n2 2" | while read A B; do echo "[$A] [$B]“; ssh localhost date; echo “ZZZ”; done

i.e. i added ’ssh localhost date’ which connect to localhost over ssh, logins to my own account, and issues “date” command (can be any command), it shows only:

[1] [1]
Tue Sep 18 15:45:24 CEST 2007
ZZZ

and finishes work. (i have a password-less login in localhost, so it doesn’t ask for password).

and the question is: why there is no second step of while loop?

( side note: i know the answer, it’s just a riddle for you :)

wersja polska

trafiłem właśnie na niezłą łamigłówkę:

poniższa linijka w bashu:

echo -e "1 1\n2 2" | while read A B; do echo "[$A] [$B]“; echo “ZZZ”; done

wypisze:

[1] [1]
ZZZ
[2] [2]
ZZZ

co jest w pełni sensowe i oczekiwane.

ale jeśli zmienię ją na:

echo -e "1 1\n2 2" | while read A B; do echo "[$A] [$B]“; ssh localhost date; echo “ZZZ”; done

tzn. dodam ’ssh localhost date’, co łączy się na moje konto na localhoście i wykonuje polecenie “date” (może to być dowolne polecenie), wynikiem całości jest tylko:

[1] [1]
Tue Sep 18 15:45:24 CEST 2007
ZZZ

i to koniec (mam logowanie bezhasłowe więc nie ma prośby o hasło).

pytanie: czemu nie ma drugiego wykonania kodu w pętli while?

( oczywiście (jak przy poprzednich łamigłówkach) znam odpowiedź ).

triggerek

2007-03-01 09:44:48 CET | 4 Comments | Tags: , ,

a dziś mam dla państwa zagadkę.

zagadka powstała wczoraj w firmie, i aż się zdziwiłem, że okazała się taka skuteczna :)

zadanie jest proste. mamy tabelkę:

create table posts (id serial primary key, paired_with int references posts (id), title text, body text);

inne kolumny są nieistotne.

i teraz - post może być sparowany lub nie. jak nie jest - w paired_with ma null’a.

jak jest - to ma tam id innego postu.

nie można być sparowanym samym z sobą.

i teraz - chcemy stworzyć trigger lub triggery które utrzymają tam porządek:

  • nie dopuszczą do parowania z samym sobą
  • pilnują by wszystkie relacje były poprawne. czyli jeśli post 1 jest sparowany z 2 to 2 musi być z 1.
  • posty mogą być wstawiane sparowane lub nie
  • posty mogą być w dowolnej chwili update’owane.

proste? pewnie, że proste.

jak masz chwilę - napisz tego triggera(y)

jako ciekawostkę mogę podać, że znajomy tworzył wczoraj coś takiego przez kilka godzin :)

aha - ów znajomy proszony jest o nie podsyłanie rozwiązania.

dlaczego “kocham” mysql’a

2007-02-19 13:57:45 CET | 15 Comments | Tags: , ,

postawiłem sobie w miarę nowego mysql’a: Server version: 5.0.32-Debian_2-log Debian etch distribution.

zrobiłem sobie testową tabelkę:

mysql> create table x (id int primary key);
Query OK, 0 rows affected (0.05 sec)

sprawdzam czy dobrze się założyła, wygląda ok:

mysql> desc x;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.08 sec)

no to teraz pora na zabawę. wstawiam tam 1 rekord:

mysql> insert into x (id) values (6);
Query OK, 1 row affected (0.06 sec)

nadal ok. to teraz wstawiam 10 rekordów z celowym błędem:

mysql> insert into x (id) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
ERROR 1062 (23000): Duplicate entry '6' for key 1

i teraz zagadka/pytanie:

ile jest rekordów w bazie?

odpowiedź - po przerwie.

- MORE -

jak rozpakować tar.gz’a.

2006-12-22 15:52:26 CET | 1 Comment | Tags:

i mamy kolejną zagadkę.
mamy na dysku .tar.gz’a o wielkości 4 gigabajty.
są w nim spakowane zdjęcia - .jpg’i - więc wielkość danych rozpakowanych będzie mocno zbliżona do wielkości archiwum.
na dysku jest tylko 1 giga wolnego miejsca.
jak to rozpakować?
dane dodatkowe - archiwum jest na pewno dobre - nie zawiera błędów, oraz, po rozpakowaniu - nie jest już nam do niczego potrzebne.
system to standardowy linux, na waniliowym jądrze, z w miarę standardowymi toolsami. ilość ramu - 1 giga.
to jest podstępna zagadka - jeśli nie będzie prawidłowych odpowiedzi w ciągu tygodnia - dam posta z prawidłową odpowiedzią :)

zagadka o bazach

2006-11-19 20:36:38 CET | 4 Comments | Tags:

dzisiejsza zagadka to praktycznie crosspost z grupy newsowej pl.comp.bazy-danych, ale nie pamiętam dokładnie kto to wtedy pisał - jak się odezwie to oczywiście dam linka.

pytanie jest relatywnie proste.

mamy dwie tabele:

CREATE TABLE tab_a (
pole_a TEXT,
pole_b TEXT
);

CREATE TABLE tab_b (
pole_c TEXT
);
wstawiamy do nich testowe dane:

INSERT INTO tab_a (pole_a, pole_b) VALUES ('a', '1');
INSERT INTO tab_a (pole_a, pole_b) VALUES ('b', '2');
INSERT INTO tab_a (pole_a, pole_b) VALUES ('c', '3');
INSERT INTO tab_a (pole_a, pole_b) VALUES ('d', '4');

INSERT INTO tab_b (pole_c) VALUES ('e');
INSERT INTO tab_b (pole_c) VALUES ('f');
na razie nic trudnego. teraz - zaraz podam zapytanie o które chodzi, proszę - nie wykonuj tego u siebie. postaraj się domyśleć co to zapytanie zwróci:

SELECT
*
FROM
tab_a
WHERE
pole_a IN ( SELECT pole_a FROM tab_b );
i teraz - co to zapytanie zwróci:

  • nic, bo się wywali z błędem. jakim?
  • nic, zwróci zero rekordów, ale błędu nie będzie.
  • zwróci jakieś rekordy. jakie? ile?

prawda, że proste? na pewno?

łamigłówki

2006-09-11 22:46:00 CEST | 9 Comments | Tags:

niniejszym chciałbym otworzyć nowy dział na blogu - łamigłówki.

będę tu co jakiś czas zamieszczał zagadki/pytania - zazwyczaj pewnie będą mocno techniczne.

nie przewiduję nagród czy nic takiego - po prostu - spróbuj się z tym zmierzyć - jak ci się uda - napisz komentarz. jeśli jeszcze nie zgadłeś - nie czytaj komentarzy. proste :)

pierwsza łamigłówka:

mamy do czynienia z serwerem linuksowym. opartym na standardowym kernelu, bez żadnych “ciekawostek” typu grsec czy selinux. standard.

serwer jest ważny, produkcyjny. pracują na nim istotne programy.

po ostatnich pracach administracyjnych zostały zalogowane 2 konsole na roota. na obu jest shell - bash.

niestety, wskutek błedu czy hacka, na maszynie została uruchomiona forkbomba.

nie ma limitów. forkbomba się forkuje i forkuje ignorując błędy. a błędy są bo wypełniła się tablica procesów. i nowe procesy nie mogą być tworzone. nie ma limitów dla roota, nic. ani root ani żaden inny user nie może stworzyć nowego procesu.
nie możemy zrobić reboot - bo serwer jest ważny. nie możemy zabijać losowych procesów - z tego samego powodu.

w jaki sposób spróbować odzyskać kontrolę nad serwerem?

od razu podpowiem, że idea: na jednej konsoli wpisuję “top”, potem zamykam drugą i wciskam szybko enter na pierwszej nie zadziałają - może i szybko przełączanie konsole, ale forkbomba na pewno szybciej zrobi kolejnego forka.