Re: obtener posicion en un file descriptor??
On Fri, 2009-02-06 at 00:39 -0300, Daniel Serpell wrote: > El Thu, Feb 05, 2009 at 06:45:35PM -0300, Aldrin Martoq escribio: > > 2009/2/4 Daniel Serpell : > > > El Tue, Feb 03, 2009 at 11:54:46PM -0300, Aldrin Martoq escribio: > > >> Al final cachureando en fs/proc/* ya estaba hecho... encontre el > > >> directorio /proc//fdinfo/ que tiene exactamente lo que necesito! > > > ¡Fantástico! ... y cómo no lo vimos antes :-) > > > Voy a guardar tu script por aquí para tenerlo presente, me ha pasado más > > > de una vez > > > necesitar esa información. > > > Por lo pronto, lo modifiqué para hacerlo un poco más robusto, ve al final. > > Lo de division por cero, bien! Ahora no se me ocurre cuando podria > > fallar el os.stat() ... > Falla cuando tienes un archivo "borrado", por ejemplo. Además, agregué > el tipo "inotify" entre los ignorados. Ok! he actualizado incluyendo formato. Slds, http://aldrin.martoq.cl/techblog/2009/02/getting-current-file-position-from-a-running-process/ -- Aldrin Martoq http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ signature.asc Description: This is a digitally signed message part
Re: obtener posicion en un file descriptor??
Hola! El Thu, Feb 05, 2009 at 06:45:35PM -0300, Aldrin Martoq escribio: > 2009/2/4 Daniel Serpell : > > El Tue, Feb 03, 2009 at 11:54:46PM -0300, Aldrin Martoq escribio: > >> Al final cachureando en fs/proc/* ya estaba hecho... encontre el > >> directorio /proc//fdinfo/ que tiene exactamente lo que necesito! > >> http://aldrin.martoq.cl/techblog/2009/02/getting-current-file-position-from-a-running-process/ > > ¡Fantástico! ... y cómo no lo vimos antes :-) > > Voy a guardar tu script por aquí para tenerlo presente, me ha pasado más de > > una vez > > necesitar esa información. > > Por lo pronto, lo modifiqué para hacerlo un poco más robusto, ve al final. > > Lo de division por cero, bien! Ahora no se me ocurre cuando podria > fallar el os.stat() ... Falla cuando tienes un archivo "borrado", por ejemplo. Además, agregué el tipo "inotify" entre los ignorados. > > Lo otro que seria interesante es que las columnas se autoajusten a su > tama~no (salvo "cmd" que no deberia ser mas grande que 12 digamos) ... > alguna implementacion bonita? > Uf, autoajustar columnas siempre es una lata (tienes que pasar dos veces por los datos), por lo que no se si vale la pena. Saludos, Daniel.
Re: obtener posicion en un file descriptor??
2009/2/4 Daniel Serpell : > El Tue, Feb 03, 2009 at 11:54:46PM -0300, Aldrin Martoq escribio: >> Al final cachureando en fs/proc/* ya estaba hecho... encontre el >> directorio /proc//fdinfo/ que tiene exactamente lo que necesito! >> http://aldrin.martoq.cl/techblog/2009/02/getting-current-file-position-from-a-running-process/ > ¡Fantástico! ... y cómo no lo vimos antes :-) > Voy a guardar tu script por aquí para tenerlo presente, me ha pasado más de > una vez > necesitar esa información. > Por lo pronto, lo modifiqué para hacerlo un poco más robusto, ve al final. Lo de division por cero, bien! Ahora no se me ocurre cuando podria fallar el os.stat() ... Lo otro que seria interesante es que las columnas se autoajusten a su tama~no (salvo "cmd" que no deberia ser mas grande que 12 digamos) ... alguna implementacion bonita? gracias por el aporte! > --- > #!/usr/bin/env python > > # Copyright(C) 2009 Aldrin Martoq ald...@martoq.cl > # Licensed under GPL v2 > > import sys, os > > cols = ['pid', 'cmd', 'fd', 'pos', 'size', '%', 'path'] > p1 = '/proc/%s/fdinfo/' > p2 = '/proc/%s/fdinfo/%s' > p3 = '/proc/%s/fd/%s' > p4 = '/proc/%s/cmdline' > > WIDTH=12 > > for i in cols: > print "%-*s" % (WIDTH, i), > print > > for pid in sys.argv[1:]: > for fd in os.listdir(p1 % pid): > d = dict(tuple(map(str.strip, l.split(':'))) >for l in open(p2 % (pid, fd))) > d['path'] = os.readlink(p3 % (pid,fd)) > for p in ['socket', 'pipe', '/dev', 'inotify']: ># skip boring fd's... >if d['path'].startswith("%s" % p): break > else: >d['fd'] = fd >d['pid'] = pid >d['cmd'] = '%*.*s' % (WIDTH, WIDTH, > open(p4 % pid).readline().strip()) >try: > d['size'] = os.stat(d['path'])[6] >except: > d['size'] = 0 >if d['size'] > 0: > d['%'] = '%5.1f' % (100.0 * int(d['pos']) / d['size']) >else: > d['%'] = ' -' >for i in cols: > print "%-*s" % (WIDTH, d[i]), >print > -- Aldrin Martoq http://aldrin.martoq.cl/
Re: obtener posicion en un file descriptor??
Hola! El Tue, Feb 03, 2009 at 11:54:46PM -0300, Aldrin Martoq escribio: > On Tue, 2009-02-03 at 17:42 -0300, Aldrin Martoq wrote: > [...] > > Otra opcion que vi _sin modificar los programas_ seria armar un modulo > > del kernel que ponga un archivo especial en /proc, y uno de el PID y > > tire un mapa de los archivos. Ej: > > # echo $PID > /proc/fdmaps > > #fd #pos > > 0 -1 > > 1 -1 > > 2 -1 > > 3 54534 > > Al final cachureando en fs/proc/* ya estaba hecho... encontre el > directorio /proc//fdinfo/ que tiene exactamente lo que necesito! > > Un programa python para aquello aca: > > http://aldrin.martoq.cl/techblog/2009/02/getting-current-file-position-from-a-running-process/ > ¡Fantástico! ... y cómo no lo vimos antes :-) Voy a guardar tu script por aquí para tenerlo presente, me ha pasado más de una vez necesitar esa información. Por lo pronto, lo modifiqué para hacerlo un poco más robusto, ve al final. Daniel. --- #!/usr/bin/env python # Copyright(C) 2009 Aldrin Martoq ald...@martoq.cl # Licensed under GPL v2 import sys, os cols = ['pid', 'cmd', 'fd', 'pos', 'size', '%', 'path'] p1 = '/proc/%s/fdinfo/' p2 = '/proc/%s/fdinfo/%s' p3 = '/proc/%s/fd/%s' p4 = '/proc/%s/cmdline' WIDTH=12 for i in cols: print "%-*s" % (WIDTH, i), print for pid in sys.argv[1:]: for fd in os.listdir(p1 % pid): d = dict(tuple(map(str.strip, l.split(':'))) for l in open(p2 % (pid, fd))) d['path'] = os.readlink(p3 % (pid,fd)) for p in ['socket', 'pipe', '/dev', 'inotify']: # skip boring fd's... if d['path'].startswith("%s" % p): break else: d['fd'] = fd d['pid'] = pid d['cmd'] = '%*.*s' % (WIDTH, WIDTH, open(p4 % pid).readline().strip()) try: d['size'] = os.stat(d['path'])[6] except: d['size'] = 0 if d['size'] > 0: d['%'] = '%5.1f' % (100.0 * int(d['pos']) / d['size']) else: d['%'] = ' -' for i in cols: print "%-*s" % (WIDTH, d[i]), print
Re: obtener posicion en un file descriptor??
On Tue, 2009-02-03 at 17:42 -0300, Aldrin Martoq wrote: [...] > Otra opcion que vi _sin modificar los programas_ seria armar un modulo > del kernel que ponga un archivo especial en /proc, y uno de el PID y > tire un mapa de los archivos. Ej: > # echo $PID > /proc/fdmaps > #fd #pos > 0 -1 > 1 -1 > 2 -1 > 3 54534 Al final cachureando en fs/proc/* ya estaba hecho... encontre el directorio /proc//fdinfo/ que tiene exactamente lo que necesito! Un programa python para aquello aca: http://aldrin.martoq.cl/techblog/2009/02/getting-current-file-position-from-a-running-process/ Slds, -- Aldrin Martoq http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ signature.asc Description: This is a digitally signed message part
Re: obtener posicion en un file descriptor??
On Tue, 2009-02-03 at 16:01 -0500, Eduardo Silva wrote: > Algo mas simple seria hacer un programa/script (en python ? :D ) para > invocar el comando deseado y capturar cuando ha leido y escrito el proceso, > ej: > mystat.py cat archivo.txt Precisamente lo contrario, necesito/quiero ver esto en procesos que ya estan ejecutandose; no que tenga que modificar el script/inicio del proceso... Puse de ejemplo el programa cat, pero imaginate una base de datos. -- Aldrin Martoq http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ signature.asc Description: This is a digitally signed message part
Re: obtener posicion en un file descriptor??
Algo mas simple seria hacer un programa/script (en python ? :D ) para invocar el comando deseado y capturar cuando ha leido y escrito el proceso, ej: mystat.py cat archivo.txt al momento de arranque de mystat.py, lanza el comando deseado, captura el PID y vas leyendo continuamente /proc/PID/io (read_bytes)... salu2.- Ed.- 2009/2/3 Aldrin Martoq > On Sat, 2009-01-31 at 21:44 -0300, Daniel Serpell wrote: > > El problema es que no resuelve la pregunta original, ya que el parche de > > biblioteca se debe aplicar *antes* de iniciar el programa. > > Yep, segun segui buscando y creo que systemtap puede entregar el $pos de > un fd (y eso cumple mis requerimientos), pero no he tenido tiempo de > probar (ademas que systemtap no viene por default AFAIK). > > Otra opcion que vi _sin modificar los programas_ seria armar un modulo > del kernel que ponga un archivo especial en /proc, y uno de el PID y > tire un mapa de los archivos. Ej: > > # echo $PID > /proc/fdmaps > #fd #pos > 0 -1 > 1 -1 > 2 -1 > 3 545345 > > Internamente deberia encontrar el task dado un pid, iterar sobre > task->files y llamar al llseek interno (vfs_lseek creo que era)... > > > Claro, uno podría mediante GDB inyectar código adicional en tiempo de > > ejecución, pero eso es bastante complejo. > > Gracias Daniel, estuvo interesante! Pero no me atreveria a pichicatear > un programa ya corriendo con GDB (ni tu solucion ni inyectar codigo). > > > La solucion de dd y pv estan buenas y no las conocia (en particular la > ultima), el problema es que tienes que reprogramar tus scripts o las > cosas que estan andando... y hay software que no puedes modificar de > esta forma (ej: una base de datos). > > > Slds, > -- > Aldrin Martoq > http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ > -- Eduardo Silva http://edsiper.linuxchile.cl
Re: obtener posicion en un file descriptor??
On Sat, 2009-01-31 at 21:44 -0300, Daniel Serpell wrote: > El problema es que no resuelve la pregunta original, ya que el parche de > biblioteca se debe aplicar *antes* de iniciar el programa. Yep, segun segui buscando y creo que systemtap puede entregar el $pos de un fd (y eso cumple mis requerimientos), pero no he tenido tiempo de probar (ademas que systemtap no viene por default AFAIK). Otra opcion que vi _sin modificar los programas_ seria armar un modulo del kernel que ponga un archivo especial en /proc, y uno de el PID y tire un mapa de los archivos. Ej: # echo $PID > /proc/fdmaps #fd #pos 0 -1 1 -1 2 -1 3 545345 Internamente deberia encontrar el task dado un pid, iterar sobre task->files y llamar al llseek interno (vfs_lseek creo que era)... > Claro, uno podría mediante GDB inyectar código adicional en tiempo de > ejecución, pero eso es bastante complejo. Gracias Daniel, estuvo interesante! Pero no me atreveria a pichicatear un programa ya corriendo con GDB (ni tu solucion ni inyectar codigo). La solucion de dd y pv estan buenas y no las conocia (en particular la ultima), el problema es que tienes que reprogramar tus scripts o las cosas que estan andando... y hay software que no puedes modificar de esta forma (ej: una base de datos). Slds, -- Aldrin Martoq http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ signature.asc Description: This is a digitally signed message part
Re: obtener posicion en un file descriptor??
Hola! El Sat, Jan 31, 2009 at 07:26:51PM -0300, Rodrigo Ahumada escribio: > Daniel Serpell escribió: >> >> Lo que yo hago normalmente es utilizar 'dd' en medio, de la siguiente >> manera: >> >> cat /mi/archivo/grande | dd | algoQueHacer >> >> Luego, le puedes mandar una señal SIGUSR1 al dd para que muestre el estado >> de la copia (por ejemplo, con "kill -USR1 $(pgrep dd)".) > > No se si será posible: si el programa que se quiere monitorear usa > fwrite o write para escribir, se tiene el código fuente como para estar > seguro de eso, se podría hacer una .so con la función fwrite o write > reescrita para que tire cada cierto avance, la posicion en el archivo, a > un archivo en /tmp..., y luego lanzar el programa haciendo que cargue el > .so antes que las libc Oh, claro que es posible, mira este ejemplo, compila con gcc -shared -fPIC -O2 -Wall -o dwrite.so dwrite.c Y luego lo usas como: LD_PRELOAD=./dwrite.so:/lib/libdl.so.2 cat /some/big/file > /dev/null El problema es que no resuelve la pregunta original, ya que el parche de biblioteca se debe aplicar *antes* de iniciar el programa. Claro, uno podría mediante GDB inyectar código adicional en tiempo de ejecución, pero eso es bastante complejo. Daniel. //-- dwrite.c --- #define _GNU_SOURCE #include #include #include #include #include ssize_t write(int fd, const void *buf, size_t count) { static ssize_t (*libc_write)(int, const void *, size_t) = 0; static ssize_t write_pos = 0, pos = 0; ssize_t r; // Get libc write function address. if( !libc_write ) libc_write = dlsym(RTLD_NEXT, "write"); // Call libc write. r = libc_write(fd,buf,count); // If FD == 1 (stdout), output to FD 2 (stderr) the current position if( fd == 1 ) { // store errno int saved_errno = errno; if( r == -1 ) write(2,"Error\n",6); else { pos += r; if( pos > write_pos ) { char buf[48]; snprintf(buf,48,"stdout:%ld\n",pos); write(2,buf,strlen(buf)); // Write only after 100 bytes write_pos = pos + 100; } } errno = saved_errno; } return r; } // end ---
Re: obtener posicion en un file descriptor??
Daniel Serpell escribió: Hola! El Fri, Jan 30, 2009 at 02:42:00AM -0300, Aldrin Martoq escribio: Estimados: Tengo un proceso laargo que esta leyendo un archivo. Me gustaria saber en que parte de ese archivo va, para asi tener una idea de cuando terminara. Algun hint? Ejemplo: $ cat /dev/sda > /dev/null Y me gustaria saber en que posicion va del archivo /dev/sda _sin modificar el codigo fuente de cat_. Algo como un ftell() pero de otro proceso. Probablemente se puede, pero no de manera facil. Se me ocurre utilizar gdb y llamar a lseek64 desde ahí. Probemos: -- # Creemos un proceso que lentamente genere caracteres y los pase # a "cat", redireccionando luego a /dev/null. $ while sleep 0.1; do echo -n "."; done | cat /dev/stdin > miArchivo.txt & # Ahora, encontremos el PID del proceso $ pgrep cat 10132 # Conectemonos con GDB al proceso y llamamos a lseek64 # con fd=STDOUT, offset=0 y whence = SEEK_CUR. $ gdb -p 10132 GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. [...] (gdb) print (long long)lseek64((int)1,(long long)0,(int)1) $1 = 140 (gdb) quit --- Si, parece posible :-), pero no se si realmente sea no invasivo. Además, en Linux lseek* no funcionan en un pipe (retornan -1 y errno en ESPIPE), por lo que no sirve si estas en medio camino de un pipe. Lo que yo hago normalmente es utilizar 'dd' en medio, de la siguiente manera: cat /mi/archivo/grande | dd | algoQueHacer Luego, le puedes mandar una señal SIGUSR1 al dd para que muestre el estado de la copia (por ejemplo, con "kill -USR1 $(pgrep dd)".) No se si será posible: si el programa que se quiere monitorear usa fwrite o write para escribir, se tiene el código fuente como para estar seguro de eso, se podría hacer una .so con la función fwrite o write reescrita para que tire cada cierto avance, la posicion en el archivo, a un archivo en /tmp..., y luego lanzar el programa haciendo que cargue el .so antes que las libc
Re: obtener posicion en un file descriptor??
Hola! El Fri, Jan 30, 2009 at 02:42:00AM -0300, Aldrin Martoq escribio: > Estimados: > > Tengo un proceso laargo que esta leyendo un archivo. Me gustaria > saber en que parte de ese archivo va, para asi tener una idea de cuando > terminara. > > Algun hint? > > Ejemplo: > $ cat /dev/sda > /dev/null > > Y me gustaria saber en que posicion va del archivo /dev/sda _sin > modificar el codigo fuente de cat_. Algo como un ftell() pero de otro > proceso. Probablemente se puede, pero no de manera facil. Se me ocurre utilizar gdb y llamar a lseek64 desde ahí. Probemos: -- # Creemos un proceso que lentamente genere caracteres y los pase # a "cat", redireccionando luego a /dev/null. $ while sleep 0.1; do echo -n "."; done | cat /dev/stdin > miArchivo.txt & # Ahora, encontremos el PID del proceso $ pgrep cat 10132 # Conectemonos con GDB al proceso y llamamos a lseek64 # con fd=STDOUT, offset=0 y whence = SEEK_CUR. $ gdb -p 10132 GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. [...] (gdb) print (long long)lseek64((int)1,(long long)0,(int)1) $1 = 140 (gdb) quit --- Si, parece posible :-), pero no se si realmente sea no invasivo. Además, en Linux lseek* no funcionan en un pipe (retornan -1 y errno en ESPIPE), por lo que no sirve si estas en medio camino de un pipe. Lo que yo hago normalmente es utilizar 'dd' en medio, de la siguiente manera: cat /mi/archivo/grande | dd | algoQueHacer Luego, le puedes mandar una señal SIGUSR1 al dd para que muestre el estado de la copia (por ejemplo, con "kill -USR1 $(pgrep dd)".) Daniel.
Re: obtener posicion en un file descriptor??
Horst H. von Brand escribió: [...] si te interesa sólo para saber donde va (no para pausar y retomar mas tarde)... busca 'pv' No es un comando comun... Google ni lo menciona entre los primeros al buscar "Unix pv command". http://www.ivarch.com/programs/pv.shtml
Re: obtener posicion en un file descriptor??
Rodrigo Ahumada wrote: > Aldrin Martoq escribió: > > Estimados: > > Tengo un proceso laargo que esta leyendo un archivo. Me gustaria > > saber en que parte de ese archivo va, para asi tener una idea de cuando > > terminara. > > Algun hint? > > Ejemplo: > > $ cat /dev/sda > /dev/null > > Y me gustaria saber en que posicion va del archivo /dev/sda _sin > > modificar el codigo fuente de cat_. Algo como un ftell() pero de otro > > proceso. > si te interesa sólo para saber donde va (no para pausar y retomar mas > tarde)... busca 'pv' No es un comando comun... Google ni lo menciona entre los primeros al buscar "Unix pv command". -- Dr. Horst H. von Brand User #22616 counter.li.org Departamento de InformaticaFono: +56 32 2654431 Universidad Tecnica Federico Santa Maria +56 32 2654239 Casilla 110-V, Valparaiso, Chile 234 Fax: +56 32 2797513
Re: obtener posicion en un file descriptor??
Aldrin Martoq escribió: [...] Buen tip el utilitario pv! el unico detalle es que debo detener el servicio y meterlo entremedio (si es que se puede)... ??? osea como: cat /dev/sda | pv --size $TAMANHO_DE_SDA | /dev/null y poder conectarse en cualquier momento para ver que esta escupiendo pv, y desconectarse después? no se podrá hacer metiendo eso en screen?
Re: obtener posicion en un file descriptor??
On Fri, Jan 30, 2009 at 2:56 AM, Rodrigo Ahumada wrote: > Aldrin Martoq escribió: >> Tengo un proceso laargo que esta leyendo un archivo. Me gustaria >> saber en que parte de ese archivo va, para asi tener una idea de cuando >> terminara. >> Algun hint? >> Ejemplo: >> $ cat /dev/sda > /dev/null >> Y me gustaria saber en que posicion va del archivo /dev/sda _sin >> modificar el codigo fuente de cat_. Algo como un ftell() pero de otro >> proceso. > si te interesa sólo para saber donde va (no para pausar y retomar mas > tarde)... busca 'pv' Buen tip el utilitario pv! el unico detalle es que debo detener el servicio y meterlo entremedio (si es que se puede)... -- Aldrin Martoq http://aldrin.martoq.cl/
Re: obtener posicion en un file descriptor??
Aldrin Martoq escribió: Estimados: Tengo un proceso laargo que esta leyendo un archivo. Me gustaria saber en que parte de ese archivo va, para asi tener una idea de cuando terminara. Algun hint? Ejemplo: $ cat /dev/sda > /dev/null Y me gustaria saber en que posicion va del archivo /dev/sda _sin modificar el codigo fuente de cat_. Algo como un ftell() pero de otro proceso. Gracias por cualquier aporte! si te interesa sólo para saber donde va (no para pausar y retomar mas tarde)... busca 'pv'
obtener posicion en un file descriptor??
Estimados: Tengo un proceso laargo que esta leyendo un archivo. Me gustaria saber en que parte de ese archivo va, para asi tener una idea de cuando terminara. Algun hint? Ejemplo: $ cat /dev/sda > /dev/null Y me gustaria saber en que posicion va del archivo /dev/sda _sin modificar el codigo fuente de cat_. Algo como un ftell() pero de otro proceso. Gracias por cualquier aporte! -- Aldrin Martoq http://aldrin.martoq.cl/videopodcast/ http://aldrin.martoq.cl/techblog/ signature.asc Description: This is a digitally signed message part