Khả năng bảo trì được của Kernel Linux P1.

1.Giới thiệu

 

Đã có rất nhiều bài báo, bài viết chỉ ra rất nhiều điểm ưu việt của Linux, một hệ thống mã nguồn mở. Nhưng cũng có một số lượng tương đương như thế những lời chỉ trích, vạch ra những yếu kém của Linux. Tôi chỉ nêu ra ý kiến của Ken Thompson (một trong số những tác giả của UNIX) đã viết trên tạp chí IEEE Computer số tháng 5 năm 1999:

 

“… Tôi không nghĩ là Linux về lâu dài sẽ thành công. Tôi đã đọc mã nguồn và thấy là có những đoạn viết tốt và có những đoạn thì không tốt. Một nhóm người ngẫu nhiên đã đóng góp cho mã nguồn này, và chất lượng thì cũng khác nhau thấy rõ. Với kinh nghiệm của tôi và một số bạn bè tôi thì Linux hoàn toàn không đáng tin cậy. Microsoft thật sự là không thể tin cậy được, nhưng Linux còn tệ hơn. Trong một môi trường không phải là máy cá nhân, vấn đề chẳng có gì to tát. Nhưng nếu bạn muốn dùng Linux làm firewall, gateway, hệ thống nhúng, … thì vẫn còn nhiều thứ phải làm lắm…”

Một điều quan trọng trong phát biểu của Thompson là “Tôi đã đọc mã nguồn”. Ý nghĩ của điều đó là, điểm khác biệt then chốt giữa Linux và Windows là Linux là phần mềm mã – nguồn – mở – bất cứ ai cũng có thể nghiên cứu mã nguồn và cho ý kiến về chất lượng của nó.

 

Tôi sẽ không đề cập đến những đặc điểm, ưu nhược của phần mềm mã nguồn mở, nếu muốn các bạn có thể tham khảo ở các bài viết khác. Với những hiểu biết cơ bản về mã nguồn mở, các bạn có thể hiểu được là phát biểu của Thompson “…có những đoạn viết tốt và có những đoạn thì không tốt…” và “… chất lượng khác nhau thấy rõ … “ không phải là không có cơ sở.

 

Tạm để qua một bên tầm vóc của Ken Thompson trong cộng đồng công nghệ phần mềm, xét theo một khía cạnh khách quan thì ý kiến của ông về chất lượng của Linux cũng mơ hồ như ý kiến của rất nhiều người dùng ủng hộ Microsoft và Windows bài xích Linux (các bạn cũng đã thấy khá nhiều trên forum này). Bởi vì, xét cho cùng, hình như Thompson không hề dùng một chuẩn mực nào (ví dụ như số lỗi dò ra được) để đo lường chất lượng mã nguồn. Hơn nữa, ông cũng không nói rõ là khi phát biểu như vậy ông đã nghiên cứu thấu đáo Linux chưa, hay chỉ là “vơ đũa cả nắm” từ một mẫu code.

 

Để chỉ ra những điểm yếu của Linux, ta cần những ý kiến cụ thể hơn, xác đáng hơn, khách quan hơn. Bài viết “Maintainability of the Linux Kernel” của các tác giả Stephen R. Schach, Bo Jin, David R. Wright, Gillian Z. Heller, A. Jefferson Offutt

 

đã thử nghiệm trên 365 phiên bản của Linux. Với mỗi phiên bản, họ đếm số thực thể (instance) của các móc nối toàn cục (common coupling) giữa 17 module trong mỗi kernel và tất cả những module khác trong các phiên bản đó. Họ đã phát hiện ra là số thể hiện của common coupling tăng theo hàm mũ (exponentially) với số của phiên bản. Kết quả này đúng đến 99,99%. Mặt khác, số dòng code trong các module của mỗi kernel chỉ tăng tuyến tính (linearly) với số của phiên bản. Qua đó, họ đã kết luận là, trừ phi Linux được tổ chức lại với số lượng common coupling nhỏ nhất, thì những quan hệ phụ thuộc ràng buộc bởi common coupling đến một ngày nào đó sẽ làm cho Linux trở nên cực kỳ khó để bảo trì (maintain) mà không gây ra lỗi.

 

Nhận thấy đây là một bài báo có ích cho người nghiên cứu mã nguồn Linux nói riêng và nghiên cứu mã nguồn mở nói chung nên tôi lược dịch và trình bày lại với một số ý kiến của mình, hy vọng giúp được gì đó cho những người quan tâm, đặc biệt là những thành viên của nhóm Operatin System trong dự án High Performance Computing của trường mình. Nếu có thể, khi chỉnh sửa mã nguồn ta sẽ làm cho Linux hòan chỉnh hơn. Have fun with FOSS!

 

2. Sự phụ thuộc giữa các module trong một software

 

2.1Coupling:

 

– Một coupling (tạm dịch là “móc nối”) giữa hai unit của một sản phẩm phần mềm là mức độ tương tác giữa các unit đó, do đó, cũng có thể nói là mức độ phụ thuộc giữa các unit.

 

– Page-Jones đưa ra ba lý do chính cho thấy việc giảm số thể hiện của coupling giữa các module là cần thiết:

 

+ Số quan hệ giữa các module càng ít thì càng giảm xác suất khi lỗi của một module xảy ra sẽ ảnh hưởng lên module khác.

 

+ Số quan hệ giữa các module càng ít thì càng giảm xác suất các thay đổi trong một module gây ra vấn đề, việc này sẽ nâng cao khả năng tái sử dụng.

 

+ Số quan hệ giữa các module càng ít thì càng giảm thời gian của lập trình viên trong việc đọc hiểu chi tiết của các module khác. (Việc này ai đã từng đọc code của Linux cũng biết vất vả như thế nào!)

 

Mặc dù tất cả các loại coupling đôi khi rất hữu ích cho thiết kế, nhưng một số lại thường dẫn đến lỗi cho phần mềm. Do đó một số loại coupling nên được giới hạn sử dụng.

 

Ví dụ:

 

Trong bảng phân loại 11 mức coupling của Offutt, mức thấp nhất là call coupling, dùng giữa module P và Q nếu P gọi Q hay Q gọi P, nhưng không có truyền tham số, tham khảo biến toàn cục, hay các tham khảo toàn cục đến các phần nằm bên ngòai giữa P và Q.

 

Trong bài viết này ta quan tâm đến common coupling, tương ứng với mức 10, global coupling. Nó được dùng khi module P và Q cùng chia sẻ một tham khảo đến một biến toàn cục.

 

2.2Vai trò của coupling:

 

Nếu một phần mềm không có coupling nào thì sản phẩm đó sẽ bao gồm một module khổng lồ, vì vậy một lượng coupling rõ ràng là cần thiết. Có nghĩa là, coupling là một hệ quả tất yếu của việc lập trình theo module.

 

Tuy nhiên, khi giữa 2 module có coupling, sẽ có một mức độ phụ thuộc giữa 2 module đó. Mức độ phụ thuộc đó có thể là cao (“strong coupling”) hay thấp (“weak coupling”). Một phần mềm được thiết kế tốt sẽ cân nhắc việc sử dụng weak coupling và tránh càng xa càng tốt strong coupling.

 

Ví dụ: call coupling là một weak coupling, common coupling là một strong coupling.

 

2.3Coupling và maintainability

 

Qua các phần trên các bạn đã thấy được mối liên quan giữa coupling với sự dễ xảy ra lỗi (fault-proneness), nhưng chưa thấy rõ ràng mối liên quan giữa coupling với khả năng bảo trì (maintainability). Mặt khác, chúng ta cũng chưa có một định nghĩa chính xác cho maintainability, do đó cũng chưa có tiêu chuẩn gì được công nhận rộng rãi cho maintainability. Tuy nhiên, ta có thể nói rằng, khi một modult là fault-prone thì nó sẽ phải trải qua nhiều lần bảo trì lặp đi lặp lại, và những thay đổi thường xuyên đó hầu như làm “lờn” đi khả năng bảo trì của nó. Hơn nữa, những thay đổi thường xuyên như vậy sẽ không chỉ giới hạn trong bản thân module bị fault – prone; việc phải thay đổi nhiều hơn một module chỉ để sửa một lỗi không phải là hiếm. Do đó, đặc tính fault-proneness của một module có thể gây bất lợi cho maintainability của một số modules khác.

 

Hay nói cách khác, dễ hiểu là strong coupling có thể gây hại cho maintainability.

 

Tại sao trong bài viết này chỉ đề cập đến common coupling? Có ba lí do:

 

Thứ nhất, trong các case study về maintainability của multiversion real-time software cho thấy, các strong coupling xuất hiện trong giai đoạn maintenance đại đa số là common coupling.

 

Thứ hai, có những tranh cãi đáng chú ý về việc chính xác là cái gì cấu thành weak hay strong coupling, và nên thống nhất theo bản phân loại coupling nào. Tuy nhiên, tất cả các bảng phân loại đều có một dạng coupling tương ứng với một common coupling kinh điển (ví dụ trong bảng ta đã nói ở trên là global coupling), và hầu như tất cả đều thống nhất là common coupling có thể gây phiền phức.

 

Thứ ba, common coupling có một thuộc tính hiểm họa là số thể hiện của common coupling giữa module M và các module khác có thể thay đổi một cách mạnh mẽ, ngay cả khi bản thân module M không hề thay đổi; cái này được gọi là clandestine common coupling. Ví du, nếu module M và N đều tham khảo đến một biến toàn cục gv, sau đó có một thể hiện của common coupling giữa M và các module khác. Nhưng nếu có 10 module khác được viết ra, tất cả đều tham khảo đến biến gv, thì số thể hiện của common coupling giữa M và các module khác sẽ tăng lên 11, mặc dù bản thân M không thay đổi gì cả.

 

3. SUCCESSIVE VERSIONS (Các phiên bản liên tiếp)

 

– Một số sản phẩm phần mềm (đặc biệt là FOSS) có quá trình phát triển song song, nghĩa là, một phiên bản chuẩn của phần mềm sẽ được mở rộng theo nhiều hướng cùng một lúc. Đôi khi, một hay nhiều nhánh trong số đó hợp nhất với nhau, trong khi các nhánh khác dừng lại.

 

– Nhắc lại cho các bạn chưa biết trong trường hợp của Linux, có hai bộ phiên bản của Linux kernel. Kernel có số version mà chữ số thứ 2 (minor number) là số chẵn (ví dụ, 2 trong 1.2.9) là phiên bản ổn định (stable). Kernel có minor number là số lẻ (vd 2.1.132) là phiên bản đang phát triển (developmental). Khi một developmental version đã đến độ “chín muồi”, nó sẽ trở thành một stable version với minor number tăng lên 1 (vd: 2.1.132 trở thành 2.2.0). Việc thay đổi minor number xảy ra khá thường xuyên, nhưng thay đổi major number (chữ số đầu tiên) trong lịch sử Linux chỉ có một lần đó là từ 1.x sang 2.x, major number chỉ tăng lên khi có một thay đổi cực lớn, tác động đến toàn bộ kernel.

 

Trong bài viết này, ta thống nhất là successive versions của version X là những version có version number và có time stamp (thời điểm công bố) liên tục nhau (theo chiều tăng dần). Ví dụ: trong Linux, version 2.0.30 đến 2.0.39 không phải là successive version vì có time stamp trễ hơn của 2.1.0. Và trong bài viết này sẽ chỉ làm việc với các successive version.

 

4. HỌ ĐÃ LÀM ĐIỀU ĐÓ NHƯ THẾ NÀO?

 

Như đã nói ở trên, module P và Q có common coupling nếu P và Q chia sẻ các tham chiếu đến cùng một biến toàn cục. Ta sẽ xem qua cách người ta (Stephen R. Schach, Bo Jin, David R. Wright … – tác giả bài báo tôi đề cập ở trên) đếm các common coupling thế nào.

 

Họ download tất cả các module của mỗi version trong 365 version của Linux. Với mỗi module trong số 17 module tạo nên kernel, họ phân loại bằng tay các biến toàn cục. Sau đó họ xác định mỗi biến toàn cục trong một module kernel được tham khảo bởi bao nhiêu module khác (mấy bước này mà không có tools như lxr thì cũng hơi bị phê!). Do chỉ tính module nên 1 module có nhiều tham chiếu đến 1 biến cục bộ cũng tính là 1, họ cũng loại những tham chiếu toàn cục đến các hằng số. Sau đó họ xác định xem mã nguồn đó có được thay đổi so với version trước không. Nếu có, họ ghi chú lại số dòng code trong version mới đó và ngày phát hành.

 

 

 

Ví dụ, version 2.1.104 của kernel module Panic.c được phát hành ngày 21 tháng 5 năm 1998, có 79 dòng code, và có 914 thể hiện của common coupling giữa module Panic.c và tất cả các modules khác trong version 2.1.104 của Linux. Số thể hiện của common coupling tăng đều lên 946 trong version 2.1.109, mặc dù code của Panic.c không hề thay đổi gì cả, một ví dụ của clandestine common coupling.

 

(còn tiếp)

 

Đông Thao

 

 

About dongthao

The best things in life, they are free ... (Cry on my shoulder lyric)
This entry was posted in Uncategorized. Bookmark the permalink.

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s