Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

384 us->srb->result); 385 us->srb->scsi_done(us->srb); 386 } else { 387 SkipForAbort: 388 US_DEBUGP("scsi command aborted\n"); 389 } 390 391 /* If an abort request was received we need to signal that 392 * the abort has finished. The proper test for this is 393 * the TIMED_OUT flag, not srb->result == DID_ABORT, because 394 * a timeout/abort request might be received after all the 112 395 * USB processing was complete. */ 396 if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) 397 complete(&(us->notify)); 398 399 /* finished working on this command */ 400 SkipForDisconnect: 401 us->srb = NULL; 402 scsi_unlock(host); 403 404 /* unlock the device pointers */ 405 up(&(us->dev_semaphore)); 406 } /* for (;;) */ 407 408 /* notify the exit routine that we're actually exiting now 409 * 410 * complete()/wait_for_completion() is similar to up()/down(), 411 * except that complete() is safe in the case where the structure 412 * is getting deleted in a parallel mode of execution (i.e. just 413 * after the down() -- that's necessary for the thread-shutdown 414 * case. 415 * 416 * complete_and_exit() goes even further than this -- it is safe in 417 * the case that the thread of the caller is going away (not just 418 * the structure) -- this is necessary for the module-remove case. 419 * This is important in preemption kernels, which transfer the flow 420 * of execution immediately upon a complete(). 421 */ 422 complete_and_exit(&(us->notify), 0); 423 } 284 行,定义了一个Scsi_Host 的指针host,令她指向us->host,也就是刚刚用scsi_host_alloc() 申请的那个Scsi_Host 结构体变量. 292 行,daemonize("usb-storage"),其实,这句话才是真正创建精灵进程的,daemonize()函数来自

内核的核心位置,kernel/exit.c 中,她完成了这么一件事情,把一个普通的进程转换成为了精灵进程,不过 此 处咱们可以不去深究精灵进程的原理,甚至咱们可以认为这句话没有做任何事情,只是从此之后咱们ps命令 一看能够看到有一个叫做usb-storage 的进程.比如下面所看到的: localhost:~ # ps -el F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 76 0 - 195 - ? 00:00:02 init 1 S 0 2 1 0 -40 - - 0 migrat ? 00:00:00 migration/0 1 S 0 3 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/0 1 S 0 18 1 0 70 -5 - 0 worker ? 00:00:00 events/0 1 S 0 26 1 0 71 -5 - 0 worker ? 00:00:00 khelper 113 1 S 0 27 1 0 70 -5 - 0 worker ? 00:00:00 kthread 1 S 0 45 27 0 72 -5 - 0 worker ? 00:00:00 kacpid 1 S 0 229 27 0 80 0 - 0 pdflus ? 00:00:00 pdflush 1 S 0 230 27 0 75 0 - 0 pdflus ? 00:00:00 pdflush 1 S 0 231 1 0 76 0 - 0 kswapd ? 00:00:00 kswapd0 1 S 0 961 27 0 70 -5 - 0 scsi_e ? 00:00:00 scsi_eh_0 1 S 0 1033 27 0 70 -5 - 0 scsi_e ? 00:00:00 scsi_eh_1 1 S 0 1045 27 0 71 -5 - 0 scsi_e ? 00:00:00 scsi_eh_2 1 S 0 1047 27 0 70 -5 - 0 worker ? 00:00:00 scsi_wq_2 5 S 0 1262 1 0 72 -4 - 1774 - ? 00:00:02 udevd 1 S 0 1939 27 0 70 -5 - 0 hub_th ? 00:00:00 khubd 1 S 0 7804 27 0 70 -5 - 0 scsi_e ? 00:00:00 scsi_eh_3 1 S 0 7805 27 0 70 -5 - 0 - ? 00:00:00 usb-storage 4 S 0 13905 13902 0 75 0 - 2430 wait pts/1 00:00:00 bash 0 R 0 19098 13905 0 77 0 - 821 - pts/1 00:00:00 ps 显然,您在终端按ctrl-c 是不可能中止这个usb-storage 进程的.这是精灵进程诸多特性中的一个,她运 行于后台.试一下kill -9 加进程号,看你能杀死她不?(系统崩溃了我可不负责哦...) 294行,这里为目前的进程设置一个flag,PF_NOFREEZE,在整个内核代码中,这个flag 也只出现过几次. 这个flag 是与电源管理相关的,2.6 的内核为了实现与Windows 相似的一个功能,Hibernate,也就是"冬 眠",(别说您不知道,Windows 关机选项里面有"关机","重启","注销","Stand by",以及"Hibernate").在 内核编译菜单里面,Power managerment options 中,有一个选项Software Suspend,也就是内核编译 选项中的CONFIG_SOFTWARE_SUSPEND,选择了她使得机器可以被suspended.显然咱们不用care 她. 但是这里之所以要设置这个flag,是因为suspend 要求把内存里的冬冬写到磁盘上,而一个进程设置了 这个flag 就表明它在suspend 的时候不会被冻住,用行话来讲就是,they’re not refrigerated during a suspend.freeze 就是冷冻,冻住的意思,过去分词frozen 是形容词,冻结的,冰冻的,其实就是让进程睡眠. 所以总的来说,这里的做法就是说,即使系统suspend 了,这个进程,或者准确地说,这个内核线程,也不应该 进入睡眠. 要执行这两个操作需要执行lock_kernel()/unlock_kernel()这一对函数.然后299 行,执行complete 唤醒前面那节的父进程.而子进程并不退出,她继续行走,她无怨无悔的行走,只不过余秋雨先生是为追寻人 类文明足迹而进行的域外旅程,而此处子进程(执)行的她对内核的守护.她像天使一般,守护着心爱的人. 于是咱们也继续跟着她行走,299 行, complete(&(us->notify)),这正是和刚才在父进程里看到的那句 使进程进入睡眠的wait_for_completion(&(us->notify))相对应,这里自然是唤醒父进程,我们先继续看

384 us->srb->result);<br />

385 us->srb->scsi_done(us->srb);<br />

386 } else {<br />

387 SkipForAbort:<br />

388 US_DEBUGP("scsi command aborted\n");<br />

389 }<br />

390<br />

391 /* If an abort request was received we need to signal that<br />

392 * the abort has finished. The proper test for this is<br />

393 * the TIMED_OUT flag, not srb->result == DID_ABORT, because<br />

394 * a timeout/abort request might be received after all the<br />

112<br />

395 * USB processing was complete. */<br />

396 if (test_bit(US_FLIDX_TIMED_OUT, &us->flags))<br />

397 complete(&(us->notify));<br />

398<br />

399 /* finished working on this command */<br />

400 SkipForDisconnect:<br />

401 us->srb = NULL;<br />

402 scsi_unlock(host);<br />

403<br />

404 /* unlock the device pointers */<br />

405 up(&(us->dev_semaphore));<br />

406 } /* for (;;) */<br />

407<br />

408 /* notify the exit routine that we're actually exiting now<br />

409 *<br />

410 * complete()/wait_for_completion() is similar to up()/down(),<br />

411 * except that complete() is safe in the case where the structure<br />

412 * is getting deleted in a parallel mode <strong>of</strong> execution (i.e. just<br />

413 * after the down() -- that's necessary for the thread-shutdown<br />

414 * case.<br />

415 *<br />

416 * complete_and_exit() goes even further than this -- it is safe in<br />

417 * the case that the thread <strong>of</strong> the caller is going away (not just<br />

418 * the structure) -- this is necessary for the module-remove case.<br />

419 * This is important in preemption kernels, which transfer the flow<br />

420 * <strong>of</strong> execution immediately upon a complete().<br />

421 */<br />

422 complete_and_exit(&(us->notify), 0);<br />

423 }<br />

284 行,定义了一个<strong>Scsi</strong>_Host 的指针host,令她指向us->host,也就是刚刚用scsi_host_alloc()<br />

申请的那个<strong>Scsi</strong>_Host 结构体变量.<br />

292 行,daemonize("usb-storage"),其实,这句话才是真正创建精灵进程的,daemonize()函数来自

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!