This is a private site! All infos, programs etc. are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN RISK! (and PLEASE DON'T TOAST YOUR HAMSTER!:)
mmh. i'm terrible in writing news, blogging etc. seems to be a better idea to look into the ChangeLog than this page. :-) the main-page might be usefull for newbies on this site too.
Ein Eierbecher darf nicht "eiPOTT" heißen!
Gut, daß diese Frage endlich mal geklärt wurde. Danke Apple!
siehe hierzu auch Hilberts 23 Probleme
oder ImmaWennSonntagIst
:)
Aus gg. Anlass ergab sich heute im Büro tatsächlich die Frage, "wie herum" denn eigentlich SCSI-Error-Messagecodes zu interpretieren sind. Gute Frage. Besonders bei der IMHO unerträglichen Schweinehitze. :-)
Also (verkürzt) konkret. Hintergrund ist die Fehlermeldung
SCSI error: return code = 0x00070000
Und die Vermutung / Behauptung:
A) es handelt sich um das "Host Code" Byte, welches hier auf 7 gesetzt ist (http://readlist.com/lists/redhat.com/linux-lvm/0/3854.html
)
B) es handelt sich hier um das "SCSI Sense" Byte, welches hier auf 7 gesetzt ist
Unabhängig von der Frage, was denn welcher der beiden Fälle bedeuten würde, nämlich ("irgendwie" konkret oder eher "diffus"):
SCSI Sense Keys, 7h == DATA PROTECT. Indicates that a command that reads or writes the medium was attempted
on a block that is protected from this operation.
The read or write operation is not performed.
Host Code, 0x07 == DID_ERROR. internal error
und ob man der LVM-Mailingliste nicht einfach vertrauen sollte, bleibt ersteinmal die Frage: ja watt denn nun? A oder B?
Also TLDP (im Archiv, also outdated)
meint:
The meaning of hd_status can be found in drivers/scsi/scsi.h: This unsigned int is composed out of different parts:
lsb | ... | ... | msb
=======|===========|===========|============
status | sense key | host code | driver byte
# http://tldp.org/HOWTO/archived/SCSI-Programming-HOWTO/SCSI-Programming-HOWTO-21.html
Ergo: Die 07 ist das 2te Byte von links. Also doch das "Sense-Key" Byte? Für mich als nicht low-level Programmierer ist sowas nicht nur bei der Hitze verwirrend. Deswegen am Besten nochmal langsam, lsb steht für least-significant-bit oder -Byte, also das niederwärtigste Bit/Byte, also jenes ganz rechts aussen, ok, und 07 ist nicht nur das 2te Byte von links sondern auch das dritte von rechts, also doch "Host Code"? Ich gebe zu den Leuten von der LVM-Liste erstmal intuitiv schneller zu glauben als anderen Aussagen, aber so richtig zufrieden bin ich damit noch nicht. Da fehlt noch etwas, um das zu untermauern.
Also um halbwegs sicher zu gehen, mache ich mir den Spass, ein wenig durch die Kernel-Sourcen zu greppen. Auch ohne grosse C-Kenntnisse geht das. Und tatsächlich, ein wenig Sucherei, et voila:
1. wo wird DID_ERROR definiert und passt das zur doku?
kiste:/usr/src/linux/include # grep -iR "DID_ERROR" ./scsi/scsi.h #define DID_ERROR 0x07 /* Internal error
OK, passt. Wenn auch nicht ganz zur Stelle, die in der (veralteten) TLDP Doku genannt wurde (drivers/scsi/scsi.h).
2. Und wo (und vor allem wie) wird nun z.B. mal so ein Wert zurückgegeben?
kiste:/usr/src/linux/drivers/scsi # grep -iR "DID_ERROR" ./* | less [...] ./libfc/fc_fcp.c: sc_cmd->result = (DID_ERROR << 16); ./wd7000.c: hosterr = DID_ERROR; [...]
Ah. Die shiften das um 16bit nach links ("<<16"), also ins dritte Byte von rechts, oder? Mal eben schnell mit Python ausprobieren (davon ausgehend es handelt sich um 32bit, also 8 Stellen in Hex-Notation):
kiste2:/mnt/bla/tmp# python -c 'print "%08x" % (07 << 0)' 00000007 kiste2:/mnt/bla/tmp# python -c 'print "%08x" % (07 << 8)' 00000700 kiste2:/mnt/bla/tmp# python -c 'print "%08x" % (07 << 16)' 00070000
Schön. Das sollte reichen, um zu glauben es ist als DID_ERROR und nicht als DATA_PROTECT zu interpretieren. In welcher Reihenfolge die Bytes zu lesen sind, ist nun schonmal klarer. Was'n toller Sommer! *g* ;-)
imho a good model is the heart of a good django app. using the the ORM (object-relational-mapper) is really a benefit then! trust me - 'cause i never managed to write a good one. :-) too often i fiddled with falling back to "dirty" raw-sql statements because a) my model was crap or b) i just was to lazy to search for how to use the ORM right.
even though i like python's "inline-documenting" systems (docstrings, ResT etc.) and django's beauty in general, i recently searched for a timesaving way of explaining a model in a way a person with no django-experience can understand. and i found it in the third-party-module "django_extensions"
.
next to a lot of things i ignored it can automatically draw a graph of your model.
cool! installation and usage is done quickly:
apt-get install python-pygraphviz # 'cauz GraphViz is used
+ install django_extensions (setup.py install; adding to INSTALLED_APPS)
./manage.py graph_models <your-model> > /tmp/model_<your-model>.dot
./manage.py graph_models <your-model> -o /tmp/model_<your-model>.png
./manage.py graph_models -a -g -o whole_project_visualized.png
![]() |
![]() |
that's it. the png file shows the relationships within your model. the dot files are its unrendered GraphViz sources - so you're free to edit them to fit "your bosses needs".
i attached 2 examples.
btw. to make things easy, on production servers it's a good idea to use as less third-party-modules as possible. imho what's not absolutely necessary should be kicked - otherwise their dependencies can lead to the boring area of fixing code while the original intention was: "let's just update or move onto another machine." example: i use the above module only on my development-laptop. if the module gets broken (i dunnot hope so, but i know why i left perl ;-). no prob. my fuzzy code will survive without any new needs i did not want to care about. :-)
ich mag enterprise-software-(support) nicht! heute hat ein nach-dau-anleitung durchgeführtes emc powerpath-update (kommerzielle mpio software) ein solaris10 komplett weggesemmelt. was nun, wenn man als "open-source mensch" solaris aus verständlichen gründen nicht so wirklich mögen kann (sprich keine freizeit investiert), es betriebsintern kein funktionierendes test-center gibbet, welches verbindliche standards definieren geschweige denn gar [1] entsprechend (verantwortlich!) patches auf verträglichkeit prüfen würde, man aber damit arbeiten muss und unter zeitdruck nicht auch noch bereit ist, sich mit dem - ääääähäm - "ignoranten" support herumzuschlagen? (stichwort: "emcgrab" ? & "yep, iturneditoffnonagain" & "no" & "hey sorry (pawel|alice|claire|justin|etc.) but that's really really not the problem here" & *schnauf*)
jau, dann freut man sich, dass man von zfs bootet und als professioneller "weichei" admin snapshots hat (naja, zugegeben nicht ganz frisch :), denn zfs hilft einem hier netterweise unverzüglich aus der patsche:
so und schon kann man nach hause gehen und die coolen sachen machen. :-)
ps: mmh. erkenntnuss02: man kann aber auch überstunden schrubben und sich magician-credits holen, weil der super-duper-proprietäre-heikles-teuerdingens-cluster abkackt und in china gerade ein sack reis umfällt und man ohgottogott sds-spiegel einsetzt und doch eigentlich alles sowas von 24x7 ist und xyz - kurz: man's halt nicht ordentlich beherrscht (oder beherrschen kann). aber, mal ehrlich, ist das denn befriedigend?? technik sollte imho freiräume (mehr zeit durch weniger arbeit) schaffen oder eben einfach spass machen (weil es interessant ist). leute bescheissen könnte man doch auch als banker!
just my 10 cents for today, ich halt jetzt wieder die klappe. ;)
[#1] oh grosses ITIL
versteh' das jetzt bitte nicht falsch wenn ich den kreativen verstand nicht direkt mit dir in einklang zu bringen vermag und deswegen stupide auf - zumindest technische - ehrlichkeit kloppe (haha, nerd-stuff)
Die Administration einer EMC Symmetrix
VMAX unterscheidet sich von der einer "klassischen" Symmetrix DMX3. Durch die Verwendung von "Autoprovisioning Groups" ab Enginuity 5874 wird das Mappen & Masken - Bullshitbingo wording zum trotz ;) - tatsächlich erheblich vereinfacht. Wo früher viele symconfigure Commands notwendig waren, führen nun einfach zu merkende symaccess Kommandos zum Ziel. symmaskdb list ist komplett weggefallen. Ähnlich wie bei anderen Storage-Arrays ist die LUN-Nummerierung auf dem SCSI-Bus nun host- und nicht mehr Frontendadapter-basiert, sprich: man kann z.B. 2 an den selben Frontendadaptern hängenden UNIX-Servern unterschiedliche Devices mit den LUN-Nummern beginnend ab 0 zuweisen. Schön das! :-)
Da mein Brötchengeber sich entschlossen hat dieses Jahr die Weltwirtschaft anzukurbeln und von DMX3 auf VMAXen zu migrieren, habe ich in nächster Zeit wahrscheinlich viele Gelegenheiten auf ganz dufte dollen proprietären & millionenschweren VMAXen zu arbeiten. Einen kurzen, nicht wirklich ordentlichen, Überblick über die wichtigsten Unterschiede in der Administration via CLI habe ich deshalb unter der Page SymmetrixVMAX begonnen.
while reading the excellent regular expression tutorial on http://www.amk.ca/python/howto/regex/
i
spent the last hours of my workday by playing with regular expressions in python. that's my first working result
reDevline = re.compile('(?P<symdev>^[0-9,a-f,A-F]{4,4})\s(?P<physicalpath>Not Visible|/dev/\w+)\s+(?P<sa>\\?{3,}|\\*{3,}|[0-9,a-f,A-F]+):(?P<saport>\\?|\
\*|\d)\s+(?P<da>[0-9,a-f,A-F]+):(?P<daport>[0-9,a-f,A-F]+)\s+(?P<config>2-Way Mir|RDF[1,2]\\+Mir|\w)\s+(?P<attribute>[N/]{0,}Grp\'d\s+(?:VCM|\([Mm]\))|[N/]{0
,}Grp\'d)\s+(?P<status>[RWDNR]{2,})\s+(?P<capacity>[\d-]+$)')
to match this storagebox stuff (in some weird way):
Symmetrix ID: 00029xxxxxxx
Device Name Directors Device
--------------------------- ------------- -------------------------------------
Cap
Sym Physical SA :P DA :IT Config Attribute Sts (MB)
--------------------------- ------------- -------------------------------------
0022 Not Visible ***:* 16D:C0 2-Way Mir N/Grp'd VCM RW 3
0023 Not Visible 08A:0 01B:D0 2-Way Mir N/Grp'd RW 3
[...]
0094 Not Visible ***:* 01D:D8 2-Way Mir N/Grp'd RW 3
0095 /dev/sdd 09C:0 16B:C8 2-Way Mir N/Grp'd RW 3
[...]
00F5 Not Visible ???:? 01D:DA 2-Way Mir N/Grp'd (M) RW 17263
00F6 Not Visible ???:? 16B:CA 2-Way Mir N/Grp'd (m) RW -
00F7 Not Visible ***:* 01A:CC RDF2+Mir N/Grp'd WD 8632
00F8 Not Visible ***:* 01B:DC RDF1+Mir N/Grp'd RW 8632
[...]
yep, thanks god tomorrow is friday! think it's really time to get a dose of something else now (no not a real life of course, what are you thinking of? *g* :-)
good night & happy weekend (it's very close! :-) !!!
Wie immer 'was spät :), aber nichtsdestotrotz: Frohes neues Jahr wünsche ich - mögen Gesundheit & Glück mit euch und denen, die euch am Herzen liegen, sein!!!
imho fängt das Jahr schonmal recht gut an, schliesslich gibt's im Januar Mary Shelley's
Frankenstein über vorleser.net
frei auf die Ohren. Hatte bisher leider nie die Zeit gefunden, das zu lesen, aber zum Hören bieten sich ja mehr alltägliche Gelegenheiten an. Tolle Sache das!
--see also: http://demfischseine.soup.io/post/10488024/Das-Jahr-f-ngt-gut-an-Homunkulus
the ability to redirect streams to python objects is a very powerfull python feature. the following code is a part of a (weird :-) puristic symmetrix-configuration-interface i'm writing on. i have a function named "do_showAvailableDevs" in it which can send its output to a pager like less but also without paging / just plain to stdout. the last possibility i use in the following case: where i redirect its output to a StringIO object (buff). the stringIO object's content is pasted into a file then, opened via vi for editing it and finally the edited content is executed via exec inside the current python scope. hell yes, i love python for making this so fun and easy!
ftmp = os.fdopen(ftmp_fd, 'w')
print >> ftmp, "# filename: ", ftmp_name, "\n\n"
if not len(args) > 0:
print >> ftmp, "self.dictUserVars = ", self.dictUserVars, "\n"
print >> ftmp, "print self.dictUserVars"
else:
for arg in args.split():
if self.dictUserVars.has_key(arg):
print >> ftmp, "self.dictUserVars['"+arg+"']="+str(self.dictUserVars[arg])
print >> ftmp, "print self.dictUserVars"
# now we redirect the stdout of a called function to a buffer
# so we can paste it into the editor
buff = StringIO.StringIO()
orig_stdout = sys.stdout
sys.stdout = buff # like print >> buff,
self.do_showAvailableDevs("",paging=0) # now all stdout goes into buff
sys.stdout = orig_stdout # restore original stream
# print >> ftmp, buff.getvalue()
for line in buff.getvalue().split('\n'):
print >> ftmp, "#", line
ftmp.close() # flush...
if os.system("vi " + ftmp_name) == 0:
print "...executing your code...\n"
ftmp = open(ftmp_name,'r')
# TODO: filter ftmp for calls like %range...
exec(ftmp) # executing an open file-object with valid python code in current scope
ftmp.close()
else:
print >> sys.stderr, "SORRY..."
--category: CategoryPython
--see also: PythonSnippets Python EMCSymmetrix
Kürzlich habe ich via VirtualBox einen Ausflug nach Indiana / OpenSolaris
unternommen. War irgendwie auf den ersten Blick sympathisch. Natürlich konnte man die Attraktion ZFS schon von weitem sehen. Nachdem mir jedoch ein pkg image-update -v das System geschrottet hat, ich natürlich keinen Snapshot hatte und den passenden Thread dazu verschlafen habe
entschied ich mich, es vorerst bei einem Kurztrip zu belassen und in's ruhige Tuxstadt zurückzukehren. Schade, dass ich nicht länger bleiben konnte. Wenigstens konnte ich mir nicht verkneifen, was mitzubringen, und zwar das schöne Nimbus-Theme, welches Sun dem Gnome spendiert hat
. Nach ca. 4 Minuten hatte ich daraus ein schönes Debian-Package
. On-the-fly incl. download, build & install. Ganz ohne Stress - ich werd' ja schliesslich auch nicht jünger. :-)
swirp (switchreport) does lightweight info-retrieval / reporting for SAN switches. it's driven by python/(p)expect under GNU/Linux. swirp has its own page on the wiki now - a tarball is attached. swirp's code is just dirtybutworkingfineformeandsomaybeforyoutoo. :)
Liebe Freunde des gepflegten Wahnsinns,
nur für den äusserst unwahrscheinlichen Fall,
dass es euch noch nicht aufgefallen ist, hier der dezente Hinweis:
"Omegamoon" - a hacker who has previously worked on ports of Fedora Linux and Google's Android phone stack to the Sharp Zaurus - has started porting Ubuntu 7.04 to Zaurus. Due to lack of time (and beeing satisfied with Ångström :) i didn't checked it out yet but it sounds very interesting. Check the following for details:
next to providing an open & no-cost I/O-multipathing-solution the DeviceMapper & multipath-tools ensure persistent naming of SAN-Devices across reboots. persistent read/write permissions to the suiting device-nodes (and additional persistent symlinks to them) can be achieved via udev.
the way of using udev to set read/write-permissions for "native-multipathed" SAN-devices on a SLES9 doesn't work on SLES10 (same on RH5 etc.). instead of using a permission-file containing the devnode-names + the permissions the stuff is written into the udev-rulesets now (/etc/udev/rules.d). for devices created by udev that's working fine (/dev/dm-<NN> and it's various symlinks ). but i wanted to use the devicenodes under /dev/mapper/ - because unlikely the symlinks which vary from distro to distro this location is found very often. sadly, udev doesn't seem to create the devnodes under /dev/mapper/ - so what doing now?
to use the /dev/mapper/-nodes i did a quick/dirty ;) workaround - just added 2 new “event-handlers” triggered by the id of the devices (mpath_id <major><minor>) of interest to do, for example, a chown oracle:oinstall && chmod 660 for them:
/etc/udev/rules.d/71-multipath.rules :
ENV{ID_DMTYPE}==”linear|multipath”, IMPORT{program}=”/sbin/mpath_id %M %m” # through mpath_id we get ID_MPATH (=WWN)
[…]
########
patterns for 2 specific disks / wwns to set oracle-permissions
# setting owner /dev/mapper/
ENV{ID_DMTYPE}==”multipath”, ENV{ID_MPATH}==”12006048000029010125[4,5]533030313030<|addotherpatternshere>″ \
SYMLINK+=”disk/by-id/$env{ID_BUS}-$env{ID_MPATH}”, PROGRAM=”/bin/chown oracle:oinstall /dev/mapper/$env{ID_MPATH}”
# doing chmod /dev/mapper/
ENV{ID_DMTYPE}==”multipath”, ENV{ID_MPATH}==”12006048000029010125[4,5]533030313030<|addotherpatternshere>″, \
SYMLINK+=”disk/by-id/$env{ID_BUS}-$env{ID_MPATH}”, PROGRAM=”/bin/chmod 660 /dev/mapper/$env{ID_MPATH}”
btw. of course, a simple init-script is a good solution too but i really like udev :-)
did i mentioned that i jumped onto python some months ago? i switched to python some months ago. :) and i really love it! of course i still use perl, bash etc. and will not rewrite from scratch what works but the point is: after some playing with python i thought "wow, i really missed sth. simple & clear like that".
often the crucial factor for changing to a new scripting language, the stuff that hooks someone like me fully are the things others already wrote and allow me to use (and change) for doing things better / in lesser time / with more fun than i could do them alone.
so here are just 3 of my favourite examples which maybe whet your appetite:
- a mighty plotting library, so i send my good old gnuplot-backend into pension
- Reinteract is a system for interactive experimentation with python. it's fun and can be used like a scratchpad with "figure-ready monster-calculator" included
- snooping into the python based webframework Django by an amazing screencast
btw. time flies much too fast! sorry i forgot to wish you all a HAPPY NEW YEAR 2008! i'm going "proactive" now ;-) :
import time year = time.localtime()[0] doy = time.localtime()[7] if doy == 1: print "HAPPY NEW YEAR %d!" % (year) else: print "have a nice day %d in year %d! :)" % (doy, year)
--category: CategoryPython
--see also: PythonSnippets Python