लिनक्स कर्नेल मॉड्यूल के भीतर फाइलें पढ़ें / लिखें


99

मैं सभी के बारे में क्यों नहीं पढ़ना चाहिए गिरी से / लिखने फ़ाइलों विचार विमर्श पता है, बजाय कैसे उपयोग करने के लिए / proc या नेटलिंक कि क्या करना है। मैं वैसे भी पढ़ना / लिखना चाहता हूं। मैंने ड्राइविंग मे नट्स - थिंग्स यू नेवर डू डू इन द कर्नेल भी पढ़ा है ।

हालाँकि, समस्या यह है कि 2.6.30 निर्यात नहीं करता है sys_read()। बल्कि इसमें लिपटा हुआ है SYSCALL_DEFINE3। इसलिए अगर मैं इसे अपने मॉड्यूल में उपयोग करता हूं, तो मुझे निम्नलिखित चेतावनी मिलती है:

WARNING: "sys_read" [xxx.ko] undefined!
WARNING: "sys_open" [xxx.ko] undefined!

स्पष्ट रूप insmodसे मॉड्यूल लोड नहीं कर सकता क्योंकि लिंकिंग सही ढंग से नहीं होती है।

प्रशन:

  • कैसे पढ़ने के लिए 2.6.22 (जहां के बाद गिरी भीतर / लिखने sys_read()/ sys_open()निर्यात नहीं कर रहे हैं)?
  • सामान्य तौर पर, SYSCALL_DEFINEn()कर्नेल के भीतर से मैक्रो में लिपटे सिस्टम कॉल का उपयोग कैसे करें ?

जवाबों:


122

आपको पता होना चाहिए कि जब संभव हो तो आपको लिनक्स कर्नेल के भीतर फ़ाइल I / O से बचना चाहिए। मुख्य विचार "एक स्तर गहरा" जाना और वीएफएस स्तर के कार्यों को कॉल करना है सीधे syscall हैंडलर के बजाय :

शामिल हैं:

#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>

एक फ़ाइल खोलना (ओपन के समान):

struct file *file_open(const char *path, int flags, int rights) 
{
    struct file *filp = NULL;
    mm_segment_t oldfs;
    int err = 0;

    oldfs = get_fs();
    set_fs(get_ds());
    filp = filp_open(path, flags, rights);
    set_fs(oldfs);
    if (IS_ERR(filp)) {
        err = PTR_ERR(filp);
        return NULL;
    }
    return filp;
}

फ़ाइल बंद करें (बंद करने के समान):

void file_close(struct file *file) 
{
    filp_close(file, NULL);
}

फ़ाइल से डेटा पढ़ना (प्रेड के समान):

int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_read(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}   

फ़ाइल में डेटा लिखना (पाइटाइट के समान):

int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

सिंकिंग एक फ़ाइल को बदलता है (fsync के समान):

int file_sync(struct file *file) 
{
    vfs_fsync(file, 0);
    return 0;
}

[संपादित करें] मूल रूप से, मैंने file_fsync का उपयोग करने का प्रस्ताव दिया, जो नए कर्नेल संस्करणों में चला गया है। बदलाव का सुझाव देने वाले गरीब आदमी की बदौलत, लेकिन जिसका बदलाव खारिज हो गया। इससे पहले कि मैं इसकी समीक्षा कर पाता, संपादन को अस्वीकार कर दिया गया।


2
धन्यवाद। मैं sys_read / sys_open कार्यक्षमता की प्रतिकृति बनाकर कुछ ऐसा ही करने की सोच रहा था। लेकिन यह बड़ी मदद है। एक जिज्ञासा, क्या SYSCALL_DEFINE का उपयोग करके घोषित सिस्टम कॉल का उपयोग करने का कोई तरीका है?
मैथोस जूल

5
मैंने इस कोड को कर्नेल 2.6.30 (Ubuntu 9.04) में आज़माया और फ़ाइल को पढ़ने से सिस्टम क्रैश हो जाता है। किसी एक ही मुद्दे का अनुभव?
एनरिको डेटोमा

@ एरिको डेटोमा? ओह वाह। इसका कोई तरीका है कि आप मुझे आपके द्वारा उपयोग किए गए मॉड्यूल दे सकते हैं? ऐसा पहले कभी नहीं देखा?
डेमिस्टर

2
यह तुरंत "आप ऐसा क्यों कर रहे हैं एफएस डांस, बीटीडब्ल्यू " का सवाल उठाते हैं, जिसका उत्तर यहां बहुत अच्छी तरह से दिया गया है: linuxjournal.com/node/8110/print "फिक्सिंग द एड्रेस स्पेस" सेक्शन के तहत।
PypeBros

@dmeister, वस्तु उर लिंक वीएफएस स्तर के कार्यों के लिए नहीं मिला
श्री

19

लिनक्स कर्नेल के संस्करण 4.14 के बाद से, vfs_readऔर vfs_writeफ़ंक्शन अब मॉड्यूल में उपयोग के लिए निर्यात नहीं किए जाते हैं । इसके बजाय, कर्नेल की फ़ाइल पहुंच के लिए विशेष रूप से कार्य दिए गए हैं:

# Read the file from the kernel space.
ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos);

# Write the file from the kernel space.
ssize_t kernel_write(struct file *file, const void *buf, size_t count,
            loff_t *pos);

इसके अलावा, filp_openअब उपयोगकर्ता-स्पेस स्ट्रिंग को स्वीकार नहीं करता है, इसलिए इसे सीधे कर्नेल एक्सेस के लिए उपयोग किया जा सकता है (नृत्य के साथ set_fs)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.