2010-04-12 4 views
2

Je traçais un processus oracle, et le trouver d'abord comme poignée fichier ouvrir un fichier /etc/netconfig11, puis en double comme 256 en appelant fcntl avec le paramètre F_DUPFD, puis close la poignée du fichier d'origine 11. Plus tard, il a lu en utilisant la poignée de fichier 256. Alors, quel est le point de dupliquer le handle de fichier? Pourquoi ne pas simplement travailler sur la poignée de fichier d'origine?quel est le but de fcntl avec le paramètre F_DUPFD

12931: 0.0006 open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 11 
12931: 0.0002 fcntl(11, F_DUPFD, 0x00000100)     = 256 
12931: 0.0001 close(11)          = 0 
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024 
12931: 0.0003 read(256, " t s   t p i _ c".., 1024) = 215 
12931: 0.0002 read(256, 0x106957054, 1024)     = 0 
12931: 0.0001 lseek(256, 0, SEEK_SET)       = 0 
12931: 0.0002 read(256, " # p r a g m a i d e n".., 1024) = 1024 
12931: 0.0003 read(256, " t s   t p i _ c".., 1024) = 215 
12931: 0.0003 read(256, 0x106957054, 1024)     = 0 
12931: 0.0001 close(256)          = 0 

Répondre

4

En aparté, ils sont fichier descripteurs plutôt que le fichier poignées. Ces derniers sont une caractéristique C utilisée avec fopen et ses frères tandis que les descripteurs sont plus UNIXy, pour une utilisation avec open et al.

Intéressant. La seule raison qui me vient à l'esprit est qu'un autre morceau de code a un besoin spécifique pour que le descripteur de fichier soit 256. Je suppose que seul Oracle connaîtrait les raisons bizarres pour cela. Dans tous les cas, vous n'êtes pas certain d'obtenir 256, vous obtenez le premier descripteur de fichier disponible supérieur ou égal à ce nombre.


d'un peu d'investigation (je ne sais pas chaque petite chose sur les entrailles d'UNIX du haut de ma tête), il y a des attributs qui appartiennent à un groupe de descripteurs dupliqués tels que le fichier position et mode d'accès. Il existe d'autres attributs qui appartiennent à un descripteur de fichier single, même lorsqu'il est dupliqué, tel que le drapeau close-on-exec dans GNULib.

Faire un double (soit avec dup, dup2 ou votre fcntl) pourrait être un moyen de créer deux descripteurs, l'un avec des attributs différents descripteur de fichier, mais je ne vois pas que d'être le cas dans votre question depuis le premier descripteur est fermé quand même. Comme vous le dites, pourquoi ne pas simplement utiliser le descripteur bas?

Chose intéressante, si vous Google pour netconfig f_dupfd, vous verrez des traces similaires où l'fcntl échoue et il continue de lire ce fichier avec le descripteur bas pour mes réflexions sur la question sont que ce soit une tentative de préserver les descripteurs bas de fichiers autant que possible. Par exemple:

4327: open("/etc/netconfig", O_RDONLY|O_LARGEFILE) = 4 
4327: fcntl(4, F_DUPFD, 0x00000100)     Err#22 EINVAL 
4327: read(4, " # p r a g m a i d e n".., 1024)  = 1024 
4327: read(4, " t s   t p i _ c".., 1024)  = 215 
4327: read(4, 0x00296B80, 1024)      = 0 
4327: lseek(4, 0, SEEK_SET)       = 0 
4327: read(4, " # p r a g m a i d e n".., 1024)  = 1024 
4327: read(4, " t s   t p i _ c".., 1024)  = 215 
4327: read(4, 0x00296B80, 1024)      = 0 
4327: close(4)          = 0 

Peut-être que le logiciel a un tableau d'octets de descripteurs de fichiers quelque part qui est limité, il tente de déplacer d'autres fichiers au-dessus du 255 limite.

Mais, en fait, c'est juste une conjecture de ma part (même si je voudrais penser que c'est une conjecture relativement intelligente). Gardez également à l'esprit que ce n'est peut-être pas Oracle lui-même qui le fait. Le contenu de netconfig est utilisé dans de nombreux endroits, ce qui peut être dû à une bibliothèque sous-jacente, en particulier du fait que la plupart des hits web mentionnés n'étaient pas spécifiques à Oracle (ftp, remsh et ainsi de suite).

+0

Merci paxdiablo, Très belle conjecture. Donne un sens à moi. – Daniel

+0

+1 J'ai appris quelque chose de nouveau. J'ai toujours supposé que 'F_DUPFD' était simplement une fonctionnalité dupliquée, mais c'est en fait la version thread-safe de' dup2' (elle évite les conditions de course où vous cloberiez un descripteur de fichier juste ouvert par un autre thread). –

5

Sur certains systèmes, comme Solaris, l'E/S standard avec FILE ne fonctionne qu'avec les descripteurs de fichier 0-255 car son implémentation de la structure FILE utilise un entier de 8 bits au lieu de int. Si un programme utilise beaucoup de descripteurs de fichiers, il est utile de réserver les descripteurs de fichier 3-255 en utilisant fnctl (fd, F_DUPFD, 256). Sinon, des fonctions comme fopen(), freopen() et fdopen() échoueront si vous avez 256 fichiers ouverts.

+0

Wow, +1 pour trouver une telle gemme de rupture dans les systèmes supposés modernes. Il n'y a aucune excuse pour qu'ils ne corrigent pas ce bug. –

+1

Avec les versions plus récentes de Solaris, vous pouvez configurer des éléments pour supprimer la limite. Cependant, cela modifie l'ABI du FICHIER, y compris la macro 'fileno' dans les anciennes versions de Solaris. Solaris n'est pas le seul système d'exploitation où les applications gâchent directement les fichiers. Par exemple, Perl l'aime, y compris en écrivant dans le champ descripteur de fichier. – jilles

2

Voici un autre exemple lorsqu'une technique de réservation de descripteurs de fichiers de faible nombre est nécessaire.

Supposons qu'un processus ouvre un grand nombre de descripteurs de fichiers, par ex. il accepte plus de 1024 connexions de socket simultanées. En même temps, le processus utilise également une bibliothèque tierce qui ouvre les connexions de socket et utilise select() pour voir si les sockets sont prêts pour la lecture ou l'écriture. En outre, la bibliothèque de tiers a été compilée avec __FD_SETSIZE défini sur 1024 (valeur par défaut). Si la bibliothèque ouvre une socket lorsque tous les descripteurs de fichiers inférieurs à 1024 sont utilisés, elle recevra un descripteur que les macros FD_ * select() et les macros FD_ * associées ne peuvent pas gérer. Cela entraînera un plantage du processus ou un comportement indéfini.

Questions connexes