2010-12-22 14 views
14

मैंने "अज्ञात इनोड" के बारे में एक Google खोज की है और ऐसा लगता है कि यह एपोल से संबंधित है ... लेकिन वास्तव में यह क्या है?लिनक्स में एक अनाम इनोड क्या है?

+1

स्वीकार किए जाते हैं जवाब देखें: http://stackoverflow.com/questions/1401359/understanding- linux-proc-id-maps – Anders

उत्तर

13

कम से कम कुछ संदर्भों में, एक अज्ञात इनोड एक संलग्न निर्देशिका प्रविष्टि के बिना एक इनोड है। इस तरह के एक inode बनाने के लिए सबसे आसान तरीका है इस तरह के रूप में है:

int fd = open("/tmp/file", O_CREAT | O_RDWR, 0666); 
unlink("/tmp/file"); 
// Note that the descriptor fd now points to an inode that has no filesystem entry; you 
// can still write to it, fstat() it, etc. but you can't find it in the filesystem. 
+0

संक्षेप में, एक अनाम इनोड एक इनोड है जो फ़ाइल का प्रतिनिधित्व नहीं कर रहा है लेकिन एक स्मृति ब्लॉक? – mrkschan

+5

नहीं, यह डिस्क पर डेटा है, लेकिन उस डेटा में फाइल सिस्टम में कोई प्रविष्टि नहीं है, जिससे इसे खोला जा सकता है - आप केवल तब तक डेटा का उपयोग कर सकते हैं जब तक कि अंतिम फ़ाइल डिस्क्रिप्टर इसे बंद नहीं करता। एक ऐसी स्थिति जिसमें आप यह चाहते हैं, जब आपको एक अस्थायी फ़ाइल की आवश्यकता होती है जिसे आप नहीं खोलना चाहते हैं; यूनिक्स में mktemp() कॉल के कई उपयोग वास्तव में ऐसे मामले हैं जहां आप अन्य प्रक्रियाओं को फ़ाइल खोलने में सक्षम नहीं होना चाहते हैं, आपको किसी कारण या किसी अन्य कारण के लिए केवल एक अस्थायी फ़ाइल की आवश्यकता है। –

+0

इस उदाहरण के लिए आप लगभग निश्चित रूप से 'O_EXCL' जोड़ना चाहते हैं और' 0666' के बजाय मोड '0600' बनाना चाहते हैं ... क्योंकि कम से कम दो प्रमुख संभावित भेद्यताएं हैं (सिम्लिंक वूलन और रेस कंडीशन विंडो जहां एक और उपयोगकर्ता फ़ाइल खोलें यदि आपका 'उमास्क' पर्याप्त प्रतिबंधित नहीं है)। –

3

openO_TMPFILE

इस के साथ अनाम नोड एक अच्छा परिभाषा होगा: यह किसी भी नाम के बिना उसकी निर्देशिका के अंदर एक आईनोड सृजित, जो ls के साथ बिल्कुल दिखाई नहीं देता है।

फिर जब आप वर्णनकर्ता को बंद करते हैं तो फ़ाइल हटा दी जाती है।

यह लिनक्स 3.11 में जोड़ा गया था।

gcc -o a.out -std=c99 -Wall -Wextra a.c 
./a.out 

anon_inode_getfd लिनक्स कर्नेल समारोह

आप कर्नेल मॉड्यूल के साथ काम कर रहे हैं, तो यह एक संभावना है:

#define _GNU_SOURCE 
#include <assert.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main(void) { 
    char buf[] = { 'a', 'b', 'c', 'd' }; 
    char buf2[] = { 'e', 'f', 'g', 'h' }; 
    int f, ret; 
    size_t off; 

    /* write */ 
    f = open(".", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); 
    ret = write(f, buf, sizeof(buf)); 

    /* Interactivelly check if anything changed on directory. It hasn't. */ 
    /*puts("hit enter to continue");*/ 
    /*getchar();*/ 

    /* read */ 
    lseek(f, 0, SEEK_SET); 
    off = 0; 
    while ((ret = read(f, buf2 + off, sizeof(buf) - off))) { 
     off += ret; 
    } 
    close(f); 
    assert(!memcmp(buf, buf2, sizeof(buf))); 

    return EXIT_SUCCESS; 
} 

उबंटू 17.04, लिनक्स 4.10 में परीक्षण किया गया, glibc 2.24, के साथ चलाने परिभाषा।

आपको इस तरह के फोन:

fd = anon_inode_getfd("random", &fops_anon, NULL, O_RDONLY | O_CLOEXEC); 

और उपयोगकर्ता के लिए fd वापसी, उदा ioctl से।

अब उपयोगकर्ता संबद्ध मनमाना file_operations और inode के साथ एक fd है, और जब कि fd बंद कर दिया है, सब कुछ कर सकती है।

यह विधि उपयोगी है उदा। यदि आप एकाधिक read सिस्कोल चाहते हैं, लेकिन एकाधिक डिवाइस फ़ाइलों को नहीं बनाना चाहते हैं, जो आगे /dev को प्रदूषित करते हैं: आप इसके बजाय अतिरिक्त ioctl s बनाते हैं।

QEMU Buildroot साथ मिनिमल runnable उदाहरण:

#include <asm/uaccess.h> /* copy_from_user, copy_to_user */ 
#include <linux/anon_inodes.h> 
#include <linux/debugfs.h> 
#include <linux/errno.h> /* EFAULT */ 
#include <linux/fs.h> 
#include <linux/jiffies.h> 
#include <linux/kernel.h> /* min */ 
#include <linux/module.h> 
#include <linux/printk.h> /* printk */ 

#include "anonymous_inode.h" 

MODULE_LICENSE("GPL"); 

static struct dentry *dir; 

static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off) 
{ 
    char kbuf[1024]; 
    size_t ret; 

    ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies); 
    if (copy_to_user(buf, kbuf, ret)) { 
     ret = -EFAULT; 
    } 
    return ret; 
} 

static const struct file_operations fops_anon = { 
    .read = read, 
}; 

static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp) 
{ 
    int fd; 

    switch (cmd) { 
     case LKMC_ANONYMOUS_INODE_GET_FD: 
      fd = anon_inode_getfd(
       "random", 
       &fops_anon, 
       NULL, 
       O_RDONLY | O_CLOEXEC 
      ); 
      if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) { 
       return -EFAULT; 
      } 
     break; 
     default: 
      return -EINVAL; 
     break; 
    } 
    return 0; 
} 

static const struct file_operations fops_ioctl = { 
    .owner = THIS_MODULE, 
    .unlocked_ioctl = unlocked_ioctl 
}; 

static int myinit(void) 
{ 
    dir = debugfs_create_dir("lkmc_anonymous_inode", 0); 
    debugfs_create_file("f", 0, dir, NULL, &fops_ioctl); 
    return 0; 
} 

static void myexit(void) 
{ 
    debugfs_remove_recursive(dir); 
} 

module_init(myinit) 
module_exit(myexit) 
संबंधित मुद्दे