ソースの表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ Share via Share via... Twitter LinkedIn Facebook Pinterest Telegram WhatsApp Yammer Reddit Teams最近の変更Send via e-Mail印刷パーマリンク × Portsにnetatalk 3.0.3がキタ━━━(゚∀゚)━━━ !!!!! Portsのnetatalk3が3.0.3に更新された。 普通に更新してもいいのだが、折角なので[netatalk-ja:0155] Re: 3.0.2でPhotoshop CS5で濁音のファイルがセーブできないのパッチを適用してみる。 この問題を簡単に解説すると、netatalkがリソースフォークを処理する際にファイル名の文字コード変換(Unicode正規化含む)が正常に働かないため、リソースフォークを持ちファイル名に非ASCII文字を含むファイルが保存できないというもの。最近はリソースフォークを持つファイルも減ったようなので(かくいう私はPantherの後半の頃からMacを使い出したのでリソースフォーク全盛の頃を知らなかったりするのだが)、殆どのnetatalk環境では問題が起きないと思われる。ファイルシステムの文字コード絡みの問題なので、ZFSでUnicode正規化を強制してるような環境でも問題は起きない(まさにうちの環境w)。 尚、パッチはTrunk開発ラインに取り込まれているので、3.0.4リリースの暁には直る模様。 果てしなく行儀が悪いけど、お手軽にportsにパッチする形でインストールする。 cd /usr/ports/net/netatalk3 sudo make patch cd work/netatalk-3.0.3 sudo curl -O http://www003.upp.so-net.ne.jp/hat/files/git-bug511-forkname.patch.gz sudo gzip -d git-bug511-forkname.patch.gz sudo patch -p1 < git-bug511-forkname.patch cd ../../ sudo make sudo make install パッチをあてると3.0.4devとしてインストールされるので確認。 $ afpd -v afpd 3.0.4dev - Apple Filing Protocol (AFP) daemon of Netatalk This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Please see the file COPYING for further information and details. afpd has been compiled with support for these features: ... よし、OKだ。 ZFS mirrorのプールがデグレードしていたでござる サーバの共有フォルダに繋がらなくなってしまった。サーバ自体は見えておりpingも通るのだが、いざ繋ごうとするとタイムアウト。その時は家のネットワークを色々弄くっていたので、それが原因かな?と気にも留めなかった。 翌日になっても繋がらなかったので、原因を調べるべくsshしたが一向に応答が帰ってこない。pingは通るのに。コンソールから直接ログインを試みるも、ユーザー名入力後に応答が帰ってこずに撃沈。これはヤバい雰囲気。仕方なく電源リセット。 幸い、問題なく起動しsshも繋がったので調査開始。 まずは /var/log/messages を見てみる。 ... Apr 19 20:24:31 Freyja kernel: mpt0: request 0xffffff800082f3a0:16151 timed out for ccb 0xfffffe0007da2800 (req->ccb 0xfffffe0007da2800) Apr 19 20:25:16 Freyja kernel: mpt0: attempting to abort req 0xffffff800082f3a0:16151 function 0 Apr 19 20:25:16 Freyja kernel: mpt0: mpt_wait_req(1) timed out Apr 19 20:25:16 Freyja kernel: mpt0: mpt_recover_commands: abort timed-out. Resetting controller Apr 19 20:25:16 Freyja kernel: mpt0: mpt_cam_event: 0x80 Apr 19 20:25:16 Freyja kernel: mpt0: mpt_cam_event: 0x80 Apr 19 20:25:16 Freyja kernel: mpt0: completing timedout/aborted req 0xffffff800082f3a0:16151 Apr 19 20:31:14 Freyja kernel: mpt0: request 0xffffff800082c460:17593 timed out for ccb 0xfffffe0007da2800 (req->ccb 0xfffffe0007da2800) Apr 19 20:31:14 Freyja kernel: mpt0: attempting to abort req 0xffffff800082c460:17593 function 0 Apr 19 20:31:18 Freyja kernel: mpt0: completing timedout/aborted req 0xffffff800082c460:17593 Apr 19 20:31:18 Freyja kernel: mpt0: abort of req 0xffffff800082c460:0 completed Apr 19 20:32:42 Freyja kernel: mpt0: request 0xffffff8000833720:17797 timed out for ccb 0xfffffe0007da2800 (req->ccb 0xfffffe0007da2800) Apr 19 20:32:45 Freyja kernel: mpt0: attempting to abort req 0xffffff8000833720:17797 function 0 Apr 19 20:32:45 Freyja kernel: mpt0: completing timedout/aborted req 0xffffff8000833720:17797 Apr 19 20:32:45 Freyja kernel: mpt0: abort of req 0xffffff8000833720:0 completed ... なんかヤバげなログががが。mptってことはHDDが逝っちゃった系・・・? 次にZFSプールの状態を見てみる。 $ zpool status pool: zroot state: DEGRADED status: One or more devices could not be opened. Sufficient replicas exist for the pool to continue functioning in a degraded state. action: Attach the missing device and online it using 'zpool online'. see: http://www.sun.com/msg/ZFS-8000-2Q scan: scrub repaired 0 in 3h41m with 0 errors on Fri Nov 2 00:13:33 2012 config: NAME STATE READ WRITE CKSUM zroot DEGRADED 0 0 0 mirror-0 DEGRADED 0 0 0 12202321002681728230 UNAVAIL 0 0 0 was /dev/da0p3 da0p3 ONLINE 0 0 0 errors: No known data errors オフフ、ミラーの片割れがUNAVAILになっとる。本来あるべきada7p3が行方不明。 camcontrol devlistで見てもada7が出てこないので本格的にお亡くなりになった?と考えつつ、最後の望みをかけてマシン開腹&ケーブルチェック。なんか微妙にSATAケーブルが緩かった気がする。いざ起動アーンドzpool status!! pool: zroot state: ONLINE status: One or more devices is currently being resilvered. The pool will continue to function, possibly in a degraded state. action: Wait for the resilver to complete. scan: resilver in progress since Sun Apr 21 11:03:14 2013 1.01G scanned out of 557G at 9.96M/s, 15h52m to go 1.01G resilvered, 0.18% done config: NAME STATE READ WRITE CKSUM zroot ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 ada7p3 ONLINE 0 0 3 (resilvering) da0p3 ONLINE 0 0 0 ktkr!! とりあえず、ハードリセットもしてしまったことだし、他のプールも含めてscrub。問題のプールは560GBで4時間ほど掛かった。 errors: No known data errors pool: zroot state: ONLINE status: One or more devices has experienced an unrecoverable error. An attempt was made to correct the error. Applications are unaffected. action: Determine if the device needs to be replaced, and clear the errors using 'zpool clear' or replace the device with 'zpool replace'. see: http://www.sun.com/msg/ZFS-8000-9P scan: scrub repaired 384K in 4h8m with 0 errors on Sun Apr 21 15:38:59 2013 config: NAME STATE READ WRITE CKSUM zroot ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 ada7p3 ONLINE 0 0 6 da0p3 ONLINE 0 0 0 errors: No known data errors よしよし、無事修復出来たようなのでzpool clearでエラーカウントをクリアして完了っと。 しかしSATAケーブルが緩むなんて事あるんだねぇ。ラッチ付きじゃないとあかんな。 Disk Arbitration Frameworkでディスクのマウントを抑制する 物理HDDをVirtualBoxのVMに割り当てて使用中、Mac OSからそのHDDをマウントされると非常に不味いので、マウントを抑制するコマンドを作ってみた。 引数にBSDデバイス名(/dev/disk5とか)を渡してコマンドを実行すると、Mac OS側からのマウントをブロックする。デバイス名は前方一致で検索しているので、/dev/disk5と書けばdisk5全体が、/dev/disk5s1と書けばdisk5のスライス1がブロック対象となる。終了はCtrl-Cで。 どこか処理が不味いようで、何かの拍子にコマンドを終了してもFinderからはマウント不能?と認識されてしまうことがある(実際はマウントされているのでopenコマンドを使えば開ける)。こうなると再起動するしかなくなる…。AS ISでおながいします。 blockMount.c // -*- coding: utf-8-unix -*- // --------------------------------------------------------- // Block Mount Utility // Copyright (c) 2013 Decomo // --------------------------------------------------------- // License: // 2-clause BSD license // Reference: // https://github.com/nanoant/mountblockd // http://stackoverflow.com/questions/3720503/how-can-i-prevent-ejection-of-a-disk-during-an-operation-on-mac-os-x // http://superuser.com/questions/336455/mac-lion-fstab-is-deprecated-so-what-replaces-it-to-prevent-a-partition-from-m // http://www.geekpage.jp/blog/?id=2011/10/4/3 // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/DiscArbitrationFramework/ // Compile: // cc BlockMount.c -g -o BlockMount -framework CoreFoundation -framework DiskArbitration // --------------------------------------------------------- #include <CoreFoundation/CoreFoundation.h> #include <DiskArbitration/DiskArbitration.h> #include <stdio.h> #include <stdlib.h> const char **g_blockDeviceList = NULL; int g_blockDeviceListCount = 0; int g_verbose = 0; int g_run = 1; DADissenterRef diskWillMount(DADiskRef disk, void *context) { const char *devName = DADiskGetBSDName(disk); DADissenterRef dissenter = NULL; if (devName) { int block=0; for (int i=0; i<g_blockDeviceListCount; i++) { if (strstr(devName, g_blockDeviceList[i])) block=1; } if (block) { if (g_verbose) fprintf(stderr, "BLOCKED mount `%s'\n", devName); dissenter = DADissenterCreate(kCFAllocatorDefault, kDAReturnNotPermitted, NULL); } } return dissenter; } void signalHandler(int sig) { switch (sig) { case SIGHUP: if (g_verbose) fprintf(stderr, "received SIGHUP, terminating...\n"); CFRunLoopStop(CFRunLoopGetCurrent()); g_run=0; break; case SIGTERM: if (g_verbose) fprintf(stderr, "received SIGTERM, terminating...\n"); CFRunLoopStop(CFRunLoopGetCurrent()); g_run=0; break; case SIGINT: if (g_verbose) fprintf(stderr, "received SIGINT, terminating...\n"); CFRunLoopStop(CFRunLoopGetCurrent()); g_run=0; break; case SIGQUIT: if (g_verbose) fprintf(stderr, "received SIGQUIT, terminating...\n"); CFRunLoopStop(CFRunLoopGetCurrent()); g_run=0; break; default: fprintf(stderr, "unhandled signal (%d) %s\n", sig, strsignal(sig)); break; } } int main(int argc, const char *argv[]) { int usage=1; if (argc >= 2) { usage=0; if (strcmp(argv[1], "-v") == 0) { g_verbose=1; g_blockDeviceList = &argv[2]; g_blockDeviceListCount = argc-2; if (argc == 2) { usage=1; } } else { g_blockDeviceList = &argv[1]; g_blockDeviceListCount = argc-1; } } if (usage) { fprintf(stderr, "usage: %s [-v] deviceName1 [deviceName2] [deviceName3] [...] \n", argv[0]); return EXIT_FAILURE; } fprintf(stderr, "blocking mount device(s) : "); for (int i=0; i<g_blockDeviceListCount; i++) { fprintf(stderr, "%s ", g_blockDeviceList[i]); } fprintf(stderr, "\n"); signal(SIGHUP, signalHandler); signal(SIGTERM, signalHandler); signal(SIGINT, signalHandler); signal(SIGQUIT, signalHandler); DAApprovalSessionRef session = DAApprovalSessionCreate(kCFAllocatorDefault); if (!session) { fprintf(stderr, "failed to create DAApprovalSession.\n"); return EXIT_FAILURE; } else { DARegisterDiskMountApprovalCallback(session, NULL, diskWillMount, NULL); DAApprovalSessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); while (g_run) { CFRunLoopRun(); } DAApprovalSessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); DAUnregisterApprovalCallback(session, diskWillMount, NULL); CFRelease(session); } return 0; } とまぁ、とりあえず作ってはみたものの、結局仮想マシンはVMware Fusionを常用してるので出番がないっていう。何だかんだでVirtualBoxは不安定なんだよねぇ。8 CPU以上使えるのは魅力的なんだけど。 NSArrayをFinder風の並び順でソートする こんなファイルがあったとする。 file-a file-1 file-01 file-2 file-10 file-b file-ab 辞書式(普通の昇順ソート)で並べ替えると file-01 file-1 file-10 file-2 file-a file-ab file-b となるわけだが、Finderでソートすると file-1 file-01 file-2 file-10 file-a file-ab file-b となる。連続した数字部分を数値と見なし、数値順で並べてくれる。個人的にはこの方が分かりやすくて好きだ。 で、この数値順ソートをCocoaで実現するにはどーしたらいいのかなー?と思って調べていたら、Technical Q&A QA1159: Sorting Like the Finderという、そのまんまの記事がADCにあった。流石林檎様、分かっていらっしゃる。 上記Q&Aのコードを改造してNSMutableArrayのカテゴリメソッドにするとスマートに使えて良い感じ。 NSString配列のソートはもちろん、任意のオブジェクトの場合はソートに使うNSStringインスタンス変数名をsortByFinderOrderWithStringObjectKey:に渡せばおk。 #include <CoreServices/CoreServices.h> #include <sys/param.h> static CFComparisonResult CompareLikeTheFinder(const void *val1, const void *val2, void *context) { SInt32 compareResult; CFStringRef lhsStr; CFStringRef rhsStr; CFIndex lhsLen; CFIndex rhsLen; UniChar lhsBuf[MAXPATHLEN]; UniChar rhsBuf[MAXPATHLEN]; // val1 is the left-hand side CFString. // val2 is the right-hand side CFString. if (context) { NSString *key = (NSString *)context; lhsStr = (CFStringRef)[(NSObject *)val1 valueForKey:key]; rhsStr = (CFStringRef)[(NSObject *)val2 valueForKey:key]; } else { lhsStr = (CFStringRef)val1; rhsStr = (CFStringRef)val2; } lhsLen = CFStringGetLength(lhsStr); rhsLen = CFStringGetLength(rhsStr); // Get the actual Unicode characters (UTF-16) for each string. CFStringGetCharacters(lhsStr, CFRangeMake(0, lhsLen), lhsBuf); CFStringGetCharacters(rhsStr, CFRangeMake(0, rhsLen), rhsBuf); // Do the comparison. UCCompareTextDefault( kUCCollateComposeInsensitiveMask | kUCCollateWidthInsensitiveMask | kUCCollateCaseInsensitiveMask | kUCCollateDigitsOverrideMask | kUCCollateDigitsAsNumberMask | kUCCollatePunctuationSignificantMask, lhsBuf, lhsLen, rhsBuf, rhsLen, NULL, &compareResult ); // Return the result. Conveniently, UCCompareTextDefault // returns -1, 0, or +1, which matches the values for // CFComparisonResult exactly. return (CFComparisonResult)compareResult; } static void SortCFMutableArrayLikeTheFinder(CFMutableArrayRef array, CFStringRef key) { CFArraySortValues( array, CFRangeMake(0, CFArrayGetCount(array)), CompareLikeTheFinder, key ); } @interface NSMutableArray (PKAdditions) - (void)sortByFinderOrder; - (void)sortByFinderOrderWithStringObjectKey:(NSString *)key; @end @implementation NSMutableArray (PKAdditions) - (void)sortByFinderOrder { [self sortByFinderOrderWithStringObjectKey:nil]; } - (void)sortByFinderOrderWithStringObjectKey:(NSString *)key { SortCFMutableArrayLikeTheFinder(self, key); } @end 実際のファイル名やディレクトリ名をソートする場合は、- [NSFileManager displayNameAtPath:(NSString *)path]で得られる名前をソートしないとFinder順にはならない。なぜかというと、Finderから見えるディレクトリ名はローカライズ(~/Documents → 書類 みたいなの)された物なので。 Portsにnetatalk 3.0.2がキタ━━━(゚∀゚)━━━ !!!!! 早速インスコ。portupgradeだと、なぜか「too few arguments to function 'load_volumes'」とビルドエラーになってしまうので、3.0.1を一旦アンインストールしたらすんなり入った(make cleanしても3.0.1のヘッダを見に行ってしまうっぽい?)。 3.0.1まではパスの扱いがおかしく、FreeBSDで[Homes]が実質機能しなかった訳だが3.0.2で無事に解決した。ありがとうHATさん。パスの扱いについては、今も検討が続いている模様。 これでafp.confもスッキリした。 ; ; Netatalk 3.x configuration file ; [Global] ; Global server settings vol preset = _DEFAULT log file = /var/log/netatalk.log [_DEFAULT] file perm = 0600 directory perm = 0700 [Homes] basedir regex = /usr/home home name = $u [Time Machine] path = /Volumes/TimeMachine time machine = yes vol size limit = 2097152 [Data] path = /Volumes/Data [Public] path = /usr/home/PUBLIC file perm = 0660 directory perm = 0770 basedir regexにはシンボリックリンクではなく、実リンクで書くのがミソ。 大事なことなのでもう一度。ありがとうHATさん。 参考ページ netatalk 3の設定でパスの扱いが変 (再検討中):HAT blog Netatalk 3.0.2 リリース (Netatalk 近状):HAT blog < Newer Posts 1 2 ... 59 60 61 62 63 64 65 ... 83 84 Older Posts > start.txt 最終更新: 2022-07-27 15:26by Decomo