Inodes vnodes


Inodes & vnodes

We know that a block on id010e is in trouble. But, we have not yet confirmed that that alone is the reason for the crashes. (Though, yes, it's a pretty safe bet.)

Before we declare id010e in need of attention from hardware support, let's look more closely at the stack tracebacks we've been getting from the dumps.

First, the routines involved:

 assfail (a, f, l)  pvn_vplist_dirty (vp, off, flags)  ufs_putpage (vp, off, len, flags, cred)  ufs_l_putpage (vp, off, len, flags, cred)  syncip (ip, flags, waitfor)  update ()  ufs_sync (vfsp) 

The calling parameters listed as vp are vnode pointers. The parameter ip is a pointer to an inode structure.

The stack traceback shows that the process that crashed was performing a file system sync. The recently updated inodes were being written back to disk. This process is done inode by inode. The syncip() routine is called by update() for each inode that needs to be sync'ed, in other words, updated on the disk.

Before we try to establish which inode syncip() was working with, take a moment to look at the definition of an inode, as described in /usr/include/ufs/inode.h .

 struct  inode {         struct  inode *i_chain[2];      /* must be first */  struct  vnode i_vnode  ;  /* vnode associated with this inode */          struct  vnode *i_devvp; /* vnode for block I/O */          u_short i_flag;          dev_t   i_dev;          /* device where inode resides */          ino_t   i_number;       /* i number, 1-to-1 with device address */          off_t   i_diroff;       /* offset in dir, where we found last entry */          struct  fs *i_fs;       /* file sys associated with this inode */          struct  dquot *i_dquot; /* quota structure controlling this file */          long    i_owner;        /* proc index of process locking inode */          long    i_count;        /* number of inode locks for i_owner */          union {           daddr_t if_nextr;     /* next byte read offset (read-ahead) */  struct socket *is_socket;         } i_un;         struct  {                 struct inode  *if_freef;        /* free list forward */                  struct inode **if_freeb;        /* free list back */          } i_fr;          struct  icommon {                 u_short ic_mode;        /*  0: mode and type of file */                  short   ic_nlink;       /*  2: number of links to file */                  uid_t   ic_uid;         /*  4: owner's user id */                  gid_t   ic_gid;         /*  6: owner's group id */                  quad    ic_size;        /*  8: number of bytes in file */  #ifdef  KERNEL                  struct timeval ic_atime; /* 16: time last accessed */                  struct timeval ic_mtime; /* 24: time last modified */                  struct timeval ic_ctime; /* 32: last time inode changed */  #else                  time_t  ic_atime;       /* 16: time last accessed */                  long    ic_atspare;                  time_t  ic_mtime;       /* 24: time last modified */                  long    ic_mtspare;                  time_t  ic_ctime;       /* 32: last time inode changed */                  long    ic_ctspare;  #endif                  daddr_t ic_db[NDADDR];  /* 40: disk block addresses */                  daddr_t ic_ib[NIADDR];  /* 88: indirect blocks */                  long    ic_flags;       /* 100: status, currently unused */                  long    ic_blocks;      /* 104: blocks actually held */                  long    ic_gen;         /* 108: generation number */                  /*                   * XXX - the disk spares were used to avoid changing                   * the size of the incore inode in a minor release.                   * Fix for 5.0 release.                   * Also remove the code in iget, iupdat that clears them.                   */                  long    ic_delaylen;    /* 112: delayed writes, units=bytes */                  long    ic_delayoff;    /* 116: where we started delaying */                  long    ic_nextrio;     /* 120: where to start the next clust */                  long    ic_writes;      /* 124: number of outstanding writes */          } i_ic;  }; 

The interesting thing about UFS inodes is that the vnode structure is built into the inode structure. Therefore, let's also look at the vnode structure, as described in /usr/include/sys/vnode.h .

 enum vtype      { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VBAD, VFIFO };  struct vnode {         u_short         v_flag;                 /* vnode flags (see below) */          u_short         v_count;                /* reference count */          u_short         v_shlockc;              /* count of shared locks */          u_short         v_exlockc;              /* count of exclusive locks */          struct vfs      *v_vfsmountedhere;      /* ptr to vfs mounted here */          struct vnodeops *v_op;                  /* vnode operations */          union {                 struct socket   *v_Socket;      /* unix ipc */                  struct stdata   *v_Stream;      /* stream */                  struct page     *v_Pages;       /* vnode pages list */          } v_s;          struct vfs      *v_vfsp;                /* ptr to vfs we are in */          enum vtype      v_type;                 /* vnode type */          dev_t           v_rdev;                 /* device (VCHR, VBLK) */          long            *v_filocks;             /* File/Record locks ... */          caddr_t         v_data;                 /* private data for fs */  }; 

Okay, we are now ready to go take a look at the inode in question in the crashes. We will also establish what process was actually running at the time of the crash.



PANIC. UNIX System Crash Dump Analysis Handbook
PANIC! UNIX System Crash Dump Analysis Handbook (Bk/CD-ROM)
ISBN: 0131493868
EAN: 2147483647
Year: 1994
Pages: 289
Authors: Chris Drake

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net