zsh and network based home directory

Environment:
Mac OS X 10.3.9
Zsh 4.1.1
Network mounted home directory


When I added the following line to my (previously empty/non-existant) ~/.zshrc

HISTFILE=~/.zsh_history

the shell froze/hang when I started a new terminal. Adding set -x to ~/.zshrc produced the following output in new terminals:


+/Network/Servers/SERVER/Users/name/.zshrc:5> HISTSIZE=1000
+/Network/Servers/SERVER/Users/name/.zshrc:6> SAVEHIST=1000
+/Network/Servers/SERVER/Users/name/.zshrc:8>
HISTFILE=/Network/Servers/SERVER/Users/name/.zsh_history


Googling didn't turn up anything. I can't update my shell because of the network based home directory.

I have also tried the 'zsh on Mac OS X' dotfiles with similar results.

Any ideas on how I can make zsh work with network based home directories?

Newton MP 2100, powerbook, powermac

Posted on Mar 1, 2006 1:02 AM

Reply
11 replies

Mar 2, 2006 7:51 AM in response to david-bo

Hi david,

They are 45 seconds off. Is that too much?


No, I think it is OK.

If the zsh hangs only if HISTFILE=xxxxx exists in .zshrc, then I guess it hangs while creating a lock file (.zsh_history.LOCK) for the history file.

Does the file ~/.zsh_history (and .zsh_history.LOCK) already exist?
If they exit, check their owner and permission, and try removing them.
Also check whether .zsh_history.xxxxxx (xxxxxx is a random string) exits or not.

If this doesn't help, then it would be helpfull to debug the hanging zsh by using gdb. Do you know how to do it?

PowerMac G4 Mac OS X (10.4.5)

Mar 2, 2006 8:45 AM in response to david-bo

If I point the history file to /tmp it works (but no lock file is created).


The lock file is deleted if the history file has been successfully read.

There are a lot of .zsh_history.PID-files in ~/


Zsh first create .zsh_history.xxxxxx and makes a hard link of it as the name .zsh_history.LOCK, and deletes .zsh_history.xxxxxx. So I guess zsh hangs when it tries to make a hard link.

The following is a quick memo of how to debug a running (or hanging) zsh:

First, setup Terminal.app so that you can open a Terminal window with a working shell (bash, tcsh, etc.). I guess you know how to do this (or already did this).

Then oepn a Terminal window (in which bash/tcsh is running), and start a zsh in the window; the zsh hangs, right?

Then open another Terminal window, and use ps command to find the PID of the zsh which is hanging. Also try to figure out whether the zsh is running (consuming the CPU cycle) or just waiting (sleeping); the STAT field in the output of ps command may contain 'R' if the zsh is running (You can also use the top command or the Activity Monitor.app).

Now in the new window, run gdb as

gdb /bin/zsh nnn

where nnn is the PID of the zsh. Then in the (gdb) prompt, type

(gdb) where

This prints the stack frames; #1 is the function in which the zsh is now, #2 is the function which called #1, etc.


If you can build zsh binary from the source code, then download the source code from the zsh website (or ftp server), and configure it with --enable-zsh-debug

./configure --enable-zsh-debug
make
make install
(install into /usr/local/bin)

Then run the zsh you have just built (/usr/local/bin/zsh). If it hangs, then (in another window) go to the Src directory of the zsh and debug the hanging zsh by gdb zsh nnn. Now you can do source-level debugging.

PowerMac G4 Mac OS X (10.4.5)

Mar 2, 2006 11:56 PM in response to Jun T.

This is the output from gdb:

% gdb /bin/zsh 26672
GNU gdb 5.3-20030128 (Apple version gdb-330.1) (Fri Jul 16 21:42:28 GMT 2004)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin".
Reading symbols for shared libraries ... done
/private/Network/Servers/SERVER/Users/username/.ssh/26672: No such file or directory.
Attaching to program: `/bin/zsh', process 26672.
Reading symbols for shared libraries ++. done
0x9a7f6bc8 in stat ()
(gdb) where
#0 0x9a7f6bc8 in stat ()
#1 0x00024e38 in lockhistfile ()
#2 0x000242c0 in readhistfile ()
#3 0x000283c4 in zsh_main ()
#4 0x0000289c in start ()
#5 0x00002710 in start ()
(gdb)

The problem is that I am in an environment where I can't install my own software. In other words, I need to get the existing version of zsh to run.

Apple is stressing Mac OS X support for netboot (and hence, network based home directories - even though I don't netboot) so I can't be the only person in my situation. Someone should have some ideas about some configuration changes I can do to make zsh run as expected.

Mar 3, 2006 3:04 AM in response to david-bo

Please double check that .zsh_history.LOCK does not exists. If it exists, then manually delete it.

Is the zsh running or sleeping?

Before starting gdb, please use top (or Activity Monitor.app) to find whether the zsh is consuming CPU cycle or just sleeping.

Or in (gdb) prompt, type

(gdb) finish

to run the program until it exits from the current function. If this returns immediately then zsh was running, while if this hangs then it was waiting for stat() to finish.

PowerMac G4 Mac OS X (10.4.5)

Mar 3, 2006 3:17 AM in response to Jun T.

No .zsh_history.LOCK:

% ls -a ~/.z*
.zcompdump .zsh_history.2217 .zsh_history.2706
.zdirdump .zsh_history.2299 .zsh_history.8251
.zsh_history.10383 .zsh_history.26672 .zsh_history.9723
.zsh_history.19418 .zsh_history.26730 .zshrc
.zsh_history.19496 .zsh_history.2702
.zsh_history.19563 .zsh_history.2704

.zsh:
. .. cache


It consumes quite a lot of CPU (10-20%):

% ps auxwww | grep 27184
user 27184 15.0 0.1 18552 780 p7 U+ 12:16PM 0:06.61 -zsh


It returns immediately:

(gdb) finish
Run till exit from #0 0x9a7f6bc8 in stat ()
0x00024e38 in lockhistfile ()
(gdb)

Mar 3, 2006 7:24 AM in response to david-bo

(I think saving history into a file is not so critical and you can live without it for a moment, during an upgrade, for example).

If you look into the source code of lockhistfile() (in hist.c), you will find there is a while loop while(link(tmpfile,lockfile)<0) { ... }</tt>. So my guess is the link() system call is failing with a strange error and your zsh is in an infinite loop.
(If you want to know what is happening, the best way is to download the source, build with --enable-zsh-debug, and do source-level debugging.)
What happens if you compile the following test code and run it in your home directory?
(Please modify the path names so that they point to your home directory)
<pre>
#include <stdio.h>
#include <unistd.h>
int main()
{
char *tmpfile = "/Network/Servers/SERVER/Users/name/.zsh_history.2217";
char *lockfile= "/Network/Servers/SERVER/Users/name/.zsh_history.LOCK";
if( link(tmpfile,lockfile) < 0 ) {
perror(NULL);
}
return 0;
}
</pre>
Save this in lock.c, and
<pre>
cc lock.c
./a.out
</pre>
If you have a file .zsh_history.2217 but do not have .zsh_history.LOCK, then a.out should end without any error message and .zsh_history.LOCK will be created.
By the way, if the pathname to your home directory contains symbolic link(s), what happens if you set HISTFILE to the true path name? For example, if /Network/Servers is a symbolic link to /automount/Servers, then
HISTFILE=/automount/Servers/SERVER/Users/name/.zsh_history
PowerMac G4 Mac OS X (10.4.5)

Mar 6, 2006 12:11 AM in response to Jun T.

I have .zsh_history.2217 but no .zsh_history.LOCK.

This is the output from your little program after changing the paths appropriately:

% ./a.out
Operation not supported

The physical path to my home directory is

/private/Network/Servers/SERVER/Users/name

(/automount/Servers/SERVER is a symbolic link to /private/Network/Servers/SERVER)

and setting

HISTFILE=/private/Network/Servers/SERVER/Users/name/.zsh_history

produced the same result as we have seen before:

+/Network/Servers/SERVER/Users/name/.zshrc:3> PATH=/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Network/Servers/SERVER/Users /name
+/Network/Servers/SERVER/Users/name/.zshrc:5> HISTSIZE=1000
+/Network/Servers/SERVER/Users/name/.zshrc:6> SAVEHIST=1000
+/Network/Servers/SERVER/Users/name/.zshrc:9> HISTFILE=/private/Network/Servers/SERVER/Users/name/.zsh_history

Newton MP 2100, powerbook powermac. no ******* macbook.

Mar 10, 2006 2:43 AM in response to david-bo

Sorry for not responding promptly.

% ./a.out
Operation not supported


On my PowerBook (10.4.4), I mounted a folder from my PowerMac (10.4.5), went to the mounted folder and ran the a.out (with appropriate changes in the path names, of course). Then I got the same result.

Also the ln command fails in an AFP-mounted directory:

% cd /Volumes/Server/
% touch old
% ln old new
Operation not supported


Either this is a bug, or a "feature", or there is a (hidden) option for afp_mount which makes the link() system call to work in a AFP-mounted directory...

PowerMac G4 Mac OS X (10.4.5)

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

zsh and network based home directory

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.