मैं एक लिनक्स ब्लॉक डिवाइस के लिए अनुरोध कतार की पहचान कैसे कर सकता हूं


80

मैं इस ड्राइवर पर काम कर रहा हूं जो नेटवर्क पर हार्ड डिस्क को जोड़ता है। एक बग है कि अगर मैं कंप्यूटर पर दो या अधिक हार्ड डिस्क को सक्षम करता हूं, तो केवल पहले वाले को विभाजन दिखाई देता है और पहचाना जाता है। इसका परिणाम यह है, अगर मेरे पास hda पर 1 विभाजन और hdb पर 1 विभाजन हैं, जैसे ही मैं hda जोड़ता हूं एक विभाजन है जिसे माउंट किया जा सकता है। इसलिए hda1 को पलक झपकते ही ब्लकि xyz123 मिल जाता है। लेकिन जब मैं आगे बढ़ता हूं और एचडीबी 1 को माउंट करता हूं तो यह उसी ब्लकिड के साथ आता है और वास्तव में, ड्राइवर इसे एचडीबी से पढ़ रहा है, एचडीबी से नहीं।

इसलिए मुझे लगता है कि मुझे वह जगह मिली जहां ड्राइवर गड़बड़ा रहा है। नीचे एक डिबग आउटपुट है जिसमें एक डंप_स्टैक शामिल है जिसे मैंने पहले स्थान पर रखा है जहाँ यह गलत डिवाइस को एक्सेस करने के लिए लगता है।

यहाँ कोड अनुभाग है:

/*basically, this is just the request_queue processor. In the log output that
  follows, the second device, (hdb) has just been connected, right after hda
  was connected and hda1 was mounted to the system. */

void nblk_request_proc(struct request_queue *q)
{
struct request *req;
ndas_error_t err = NDAS_OK;

dump_stack();

while((req = NBLK_NEXT_REQUEST(q)) != NULL)
{
    dbgl_blk(8,"processing queue request from slot %d",SLOT_R(req));

    if (test_bit(NDAS_FLAG_QUEUE_SUSPENDED, &(NDAS_GET_SLOT_DEV(SLOT_R(req))->queue_flags)))  {
        printk ("ndas: Queue is suspended\n");
        /* Queue is suspended */
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) )
        blk_start_request(req);
#else
        blkdev_dequeue_request(req);
#endif

यहाँ एक लॉग आउटपुट है। मैंने यह समझने में मदद करने के लिए कुछ टिप्पणियां जोड़ी हैं कि क्या हो रहा है और खराब कॉल कहां आ रही है।

  /* Just below here you can see "slot" mentioned many times. This is the 
     identification for the network case in which the hd is connected to the 
     network. So you will see slot 2 in this log because the first device has 
     already been connected and mounted. */

  kernel: [231644.155503] BL|4|slot_enable|/driver/block/ctrldev.c:281|adding disk: slot=2, first_minor=16, capacity=976769072|nd/dpcd1,64:15:44.38,3828:10
  kernel: [231644.155588] BL|3|ndop_open|/driver/block/ops.c:233|ing bdev=f6823400|nd/dpcd1,64:15:44.38,3720:10
  kernel: [231644.155598] BL|2|ndop_open|/driver/block/ops.c:247|slot =0x2|nd/dpcd1,64:15:44.38,3720:10
  kernel: [231644.155606] BL|2|ndop_open|/driver/block/ops.c:248|dev_t=0x3c00010|nd/dpcd1,64:15:44.38,3720:10
  kernel: [231644.155615] ND|3|ndas_query_slot|netdisk/nddev.c:791|slot=2 sdev=d33e2080|nd/dpcd1,64:15:44.38,3696:10
  kernel: [231644.155624] ND|3|ndas_query_slot|netdisk/nddev.c:817|ed|nd/dpcd1,64:15:44.38,3696:10
  kernel: [231644.155631] BL|3|ndop_open|/driver/block/ops.c:326|mode=1|nd/dpcd1,64:15:44.38,3720:10
  kernel: [231644.155640] BL|3|ndop_open|/driver/block/ops.c:365|ed open|nd/dpcd1,64:15:44.38,3724:10
  kernel: [231644.155653] BL|8|ndop_revalidate_disk|/driver/block/ops.c:2334|gendisk=c6afd800={major=60,first_minor=16,minors=0x10,disk_name=ndas-44700486-0,private_data=00000002,capacity=%lld}|nd/dpcd1,64:15:44.38,3660:10
  kernel: [231644.155668] BL|8|ndop_revalidate_disk|/driver/block/ops.c:2346|ed|nd/dpcd1,64:15:44.38,3652:10

  /* So at this point the hard disk is added (gendisk=c6...) and the identifications
     all match the network device. The driver is now about to begin scanning the 
     hard drive for existing partitions. the little 'ed', at the end of the previous
     line indicates that revalidate_disk has finished it's job. 

     Also, I think the request queue is indicated by the output dpcd1 near the very
     end of the line. 

     Now below we have entered the function that is pasted above. In the function
     you can see that the slot can be determined by the queue. And the log output
     after the stack dump shows it is from slot 1. (The first network drive that was
     already mounted.) */

        kernel: [231644.155677]  ndas-44700486-0:Pid: 467, comm: nd/dpcd1 Tainted: P           2.6.32-5-686 #1
  kernel: [231644.155711] Call Trace:
  kernel: [231644.155723]  [<fc5a7685>] ? nblk_request_proc+0x9/0x10c [ndas_block]
  kernel: [231644.155732]  [<c11298db>] ? __generic_unplug_device+0x23/0x25
  kernel: [231644.155737]  [<c1129afb>] ? generic_unplug_device+0x1e/0x2e
  kernel: [231644.155743]  [<c1123090>] ? blk_unplug+0x2e/0x31
  kernel: [231644.155750]  [<c10cceec>] ? block_sync_page+0x33/0x34
  kernel: [231644.155756]  [<c108770c>] ? sync_page+0x35/0x3d
  kernel: [231644.155763]  [<c126d568>] ? __wait_on_bit_lock+0x31/0x6a
  kernel: [231644.155768]  [<c10876d7>] ? sync_page+0x0/0x3d
  kernel: [231644.155773]  [<c10876aa>] ? __lock_page+0x76/0x7e
  kernel: [231644.155780]  [<c1043f1f>] ? wake_bit_function+0x0/0x3c
  kernel: [231644.155785]  [<c1087b76>] ? do_read_cache_page+0xdf/0xf8
  kernel: [231644.155791]  [<c10d21b9>] ? blkdev_readpage+0x0/0xc
  kernel: [231644.155796]  [<c1087bbc>] ? read_cache_page_async+0x14/0x18
  kernel: [231644.155801]  [<c1087bc9>] ? read_cache_page+0x9/0xf
  kernel: [231644.155808]  [<c10ed6fc>] ? read_dev_sector+0x26/0x60
  kernel: [231644.155813]  [<c10ee368>] ? adfspart_check_ICS+0x20/0x14c
  kernel: [231644.155819]  [<c10ee138>] ? rescan_partitions+0x17e/0x378
  kernel: [231644.155825]  [<c10ee348>] ? adfspart_check_ICS+0x0/0x14c
  kernel: [231644.155830]  [<c10d26a3>] ? __blkdev_get+0x225/0x2c7
  kernel: [231644.155836]  [<c10ed7e6>] ? register_disk+0xb0/0xfd
  kernel: [231644.155843]  [<c112e33b>] ? add_disk+0x9a/0xe8
  kernel: [231644.155848]  [<c112dafd>] ? exact_match+0x0/0x4
  kernel: [231644.155853]  [<c112deae>] ? exact_lock+0x0/0xd
  kernel: [231644.155861]  [<fc5a8b80>] ? slot_enable+0x405/0x4a5 [ndas_block]
  kernel: [231644.155868]  [<fc5a8c63>] ? ndcmd_enabled_handler+0x43/0x9e [ndas_block]
  kernel: [231644.155874]  [<fc5a8c20>] ? ndcmd_enabled_handler+0x0/0x9e [ndas_block]
  kernel: [231644.155891]  [<fc54b22b>] ? notify_func+0x38/0x4b [ndas_core]
  kernel: [231644.155906]  [<fc561cba>] ? _dpc_cancel+0x17c/0x626 [ndas_core]
  kernel: [231644.155919]  [<fc562005>] ? _dpc_cancel+0x4c7/0x626 [ndas_core]
  kernel: [231644.155933]  [<fc561cba>] ? _dpc_cancel+0x17c/0x626 [ndas_core]
  kernel: [231644.155941]  [<c1003d47>] ? kernel_thread_helper+0x7/0x10

  /* here are the output of the driver debugs. They show that this operation is
     being performed on the first devices request queue. */

  kernel: [231644.155948] BL|8|nblk_request_proc|/driver/block/block26.c:494|processing queue request from slot 1|nd/dpcd1,64:15:44.38,3408:10
  kernel: [231644.155959] BL|8|nblk_handle_io|/driver/block/block26.c:374|struct ndas_slot sd = NDAS GET SLOT DEV(slot 1)
  kernel: [231644.155966] |nd/dpcd1,64:15:44.38,3328:10
  kernel: [231644.155970] BL|8|nblk_handle_io|/driver/block/block26.c:458|case READA call ndas_read(slot=1, ndas_req)|nd/dpcd1,64:15:44.38,3328:10
  kernel: [231644.155979] ND|8|ndas_read|netdisk/nddev.c:824|read io: slot=1, cmd=0, req=x00|nd/dpcd1,64:15:44.38,3320:10

मुझे उम्मीद है कि यह पर्याप्त पृष्ठभूमि जानकारी है। हो सकता है कि इस समय एक स्पष्ट सवाल यह है कि "request_queues कब और कहाँ सौंपा गया है?"

खैर जो add_disk फ़ंक्शन से पहले थोड़ा सा नियंत्रित किया जाता है। डिस्क जोड़ना, लॉग आउटपुट पर पहली पंक्ति है।

slot->disk = NULL;
spin_lock_init(&slot->lock);
slot->queue = blk_init_queue(
    nblk_request_proc, 
    &slot->lock
);

जहां तक ​​मुझे पता है, यह मानक संचालन है। तो वापस अपने मूल प्रश्न पर। क्या मुझे कहीं से अनुरोध कतार मिल सकती है और यह सुनिश्चित कर सकती है कि यह प्रत्येक नए उपकरण के लिए बढ़ा या अद्वितीय है या लिनक्स कर्नेल केवल प्रत्येक प्रमुख संख्या के लिए एक कतार का उपयोग करता है? मैं यह जानना चाहता हूं कि यह ड्राइवर एक ही कतार को दो अलग-अलग ब्लॉक स्टोरेज पर क्यों लोड कर रहा है, और यह निर्धारित करें कि प्रारंभिक पंजीकरण प्रक्रिया के दौरान डुप्लिकेट ब्लेक का कारण बन रहा है या नहीं।

मेरे लिए इस स्थिति को देखने के लिए धन्यवाद।


8
आप कर्नेल Newbies मेलिंग सूची की कोशिश करना चाहते हो सकता है ।
dlitz 10

1
@ndasusers: यह एक नया xx_request (req) शुरू करने से पहले अनुरोध के 'प्रकार' की जांच करने के लिए समझ में आता है। हो सकता है कि आने वाला अनुरोध केवल आपके पहले से ही माउंट किए गए hda के लिए एक रीड एक्सेस के बारे में हो और आप इसे संभालते हैं जैसे कि ताजे प्लग किए गए एचडीबी से संबंधित कुछ।
Boto

1
आपने hdab1 लिखा और माउंट किया, यह भी आता है मुझे लगता है कि आपका मतलब hdb1 सही है?
यवेस मार्टिन

मुझे नहीं लगता कि आपके पास एक ही प्रमुख और मामूली संख्या वाले दो डिवाइस हो सकते हैं। ड्राइव के लिए आपकी छोटी और बड़ी संख्या क्या है?
एथन

अच्छा सवाल है, लेकिन क्या आप nbd को फिर से लागू करने की कोशिश कर रहे हैं ?
इयानॉर्टन

जवाबों:



0

मैं बग का समाधान साझा करता हूं जिसके कारण मुझे यह प्रश्न पोस्ट करना पड़ा। हालांकि यह वास्तव में इस सवाल का जवाब नहीं देता है कि डिवाइस अनुरोध कतार की पहचान कैसे करें।

उपरोक्त कोड में निम्नलिखित है:

if (test_bit(NDAS_FLAG_QUEUE_SUSPENDED, 
       &(NDAS_GET_SLOT_DEV(SLOT_R(req))->queue_flags))) 

खैर, वह "SLOT_R (req)" परेशानी पैदा कर रहा था। यह परिभाषित किया गया है कि जेंडिस्क डिवाइस को वापस कहां करना है।

#define SLOT_R(_request_) SLOT((_request_)->rq_disk)

इसने डिस्क को वापस कर दिया, लेकिन बाद में विभिन्न कार्यों के लिए उचित मूल्य नहीं। इसलिए अतिरिक्त ब्लॉक उपकरणों को लोड किए जाने के बाद, यह फ़ंक्शन मूल रूप से 1. लौटा रहा (मुझे लगता है कि यह एक बूलियन के रूप में प्रसंस्करण कर रहा था।) इसलिए, सभी अनुरोधों को डिस्क 1 के लिए अनुरोध कतार पर ढेर किया गया था।

यह फिक्स डिस्क डिस्क पहचान मूल्य तक पहुंचने के लिए था जो पहले से ही डिस्क के Private_data में संग्रहीत था जब इसे सिस्टम में जोड़ा गया था।

Correct identifier definition:
   #define SLOT_R(_request_) ( (int) _request_->rq_disk->private_data )

How the correct disk number was stored.
   slot->disk->queue = slot->queue;
   slot->disk->private_data = (void*) (long) s;  <-- 's' is the disk id
   slot->queue_flags = 0;

अब सही डिस्क आईडी को निजी डेटा से लौटा दिया गया है, इसलिए सभी सही कतार के लिए अनुरोध करते हैं।

जैसा कि उल्लेख किया गया है, यह नहीं दिखाता है कि कतार की पहचान कैसे करें। एक गैर-शिक्षित अनुमान हो सकता है:

 x = (int) _request_->rq_disk->queue->id;

संदर्भ। request_queue फ़ंक्शन लिनक्स में http://lxr.free-electrons.com/source/include/linux/blkdev.h#L270 और 321

मदद करने के लिए सभी को धन्यवाद!


पिछली टिप्पणियों के जवाब में: -बोटो: अनुरोधों का इस फ़ंक्शन में और नीचे परीक्षण किया गया है। त्रुटि वास्तव में दूसरी जगह हो रही थी SLOT_R का उपयोग किया जा रहा था। -Yves: सुधार के लिए धन्यवाद। यह मेरी गलती थी। -ईथन: डिस्क मेजर और माइनर्स सही आएंगे, लगभग सभी मामलों में जिन्हें वे खोजे गए थे। -Ian: यह NDAS है। यह काफी हद तक nbd की तरह है, यह लैन पर ब्लॉक स्टोरेज प्रदान करता है। NDAS हालांकि वास्तविक हार्डवेयर है। अन्य करीबी कार्यान्वयन एओई है।
ndasusers
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.