Revisiting Old APIs
It has been over a year since this column started, and due to the rapid rate of Linux kernel development, much of what was written back then is now wrong. This month, we cover the changes in the different kernel APIs that have been discussed previously.
The tty layer had been one of the most stable kernel APIs around, and it showed. The lack of proper reference counting, the locking shoved in where it looked needed and the strange way tty devices were allocated are all due to its age. Thankfully, Al Viro recently cleaned up a lot of the old cruft in the tty layer in the 2.5 kernel series. Because of this, a number of things have changed for anyone wanting to write a new tty driver.
In the August and October 2002 issues of LJ [available at /article/5896 and /article/6226], we discussed the tty layer and how to fill up the struct tty_driver structure with all the necessary function callbacks. Since then, a new structure, struct tty_operations, has been created to hold all of the function callbacks. The struct tty_driver still contains the older function pointers, so a new function has been created to copy these pointers over, tty_set_operations. Hopefully, this duplication will be eliminated soon.
A number of variables have been removed from the struct tty_driver. The table, termios, termios_locked and refcount fields are gone. The tty layer now handles all of the proper locking and reference counting, without forcing the individual tty drivers to allocate the space for these locks.
The magic and num variables no longer need to be set explicitly by the tty driver. These variables now are set in a new function, alloc_tty_driver, that must be called by all tty drivers to allocate the space for the tty driver. The number of different tty devices this driver is going to support is passed as a parameter to the function. For example, the tiny tty driver introduced in the original tty articles would create the struct tty_driver as:
/* allocate the tty driver */ tiny_tty_driver = alloc_tty_driver(TINY_TTY_MINORS);
In the past, picking the proper name for the tty driver was difficult, as the devfs kernel option overloaded the use of the name field. Christoph Hellwig finally fixed this mess by introducing a new variable in the struct tty_driver structure called devfs_name. Now, the name field should be set to a simple, small name that shows up in the tty proc files. The devfs_name should be set to the name that devfs uses to generate the device node for this driver.
In the 2.5 kernel series, the MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros were declared too racy, and almost all usage of them in the kernel was removed. In order to do this, module reference counting was pushed a layer higher than the original calls. This allows the kernel to increment a module's reference count before the kernel jumps into the module. Likewise, when the kernel is finished with the module, it knows to decrement the count automatically.
This module change was done in the tty layer, so no tty driver should contain the MOD_* macros. Instead, an owner variable was added to the struct tty_driver to show what module owns the tty driver. The following line shows how to set this variable properly:
tiny_tty_driver->owner = THIS_MODULE;
This tells the tty core what module is related to this tty driver.
As for these tty changes, here is how to initialize and register a tty driver with the kernel properly:
#define TINY_TTY_MAJOR240 /* experimental range */
#define TINY_TTY_MINORS 255
/* use the whole major up */
static struct tty_operations serial_ops = {
.open = tiny_open,
.close = tiny_close,
.write = tiny_write,
.write_room = tiny_write_room,
};
static struct tty_driver *tiny_tty_driver;
static int __init tiny_init(void)
{
/* allocate the tty driver */
tiny_tty_driver =
alloc_tty_driver(TINY_TTY_MINORS);
/* initialize the tty driver */
tiny_tty_driver->owner = THIS_MODULE;
tiny_tty_driver->driver_name = "tiny_tty";
tiny_tty_driver->name = "ttty";
tiny_tty_driver->devfs_name = "tts/ttty%d";
tiny_tty_driver->major = TINY_TTY_MAJOR,
tiny_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
tiny_tty_driver->subtype = SERIAL_TYPE_NORMAL,
tiny_tty_driver->flags =
TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
tiny_tty_driver->init_termios = tty_std_termios;
tiny_tty_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
tty_set_operations(tiny_tty_driver, &serial_ops);
if (tty_register_driver(tiny_tty_driver)) {
printk(KERN_ERR
"failed to register tiny tty driver");
return -1;
}
printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
static void __exit tiny_exit (void)
{
tty_unregister_driver(tiny_tty_driver);
}
module_init(tiny_init);
module_exit(tiny_exit);
tty callout devices also are now removed entirely from the kernel. Any tty driver living in the 2.5 kernel tree that used callout support has had it removed.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Home, My Backup Data Center
- RSS Feeds
- New Products
- Trying to Tame the Tablet
- What's the tweeting protocol?
- Dart: a New Web Programming Experience




4 hours 39 sec ago
6 hours 23 min ago
23 hours 11 min ago
1 day 1 hour ago
1 day 3 hours ago
1 day 3 hours ago
1 day 3 hours ago
1 day 8 hours ago
1 day 9 hours ago
1 day 11 hours ago