Displaying Newsletter
Issue 50, 14 Dec 2003


  In This Issue:
 
Editor's Note by Kevin Field 

Well, I could say what I said back in August about trying to get newsletter editions out more often, but instead I'll just say this: When the OBOS developers are quiet, you know it's because they're working through the tough parts. Now give it up for our newsletter writers, who, despite the busiest of schedules, have cranked out something for you to enjoy!

 
System Logging by Axel Dörfler 

The system logging capabilities in BeOS are built on top of the syslog interface as defined by the POSIX standard. In addition to the functionality provided by that standard, it has some BeOS specific extensions.

The following article will give an overview about how this service works internally in OpenBeOS, and how it can be used in applications. The implementation as done in OpenBeOS might differ from the actual implementation in BeOS, but it is fully binary compatible.

The syslog_daemon

The syslog service is provided by a standard BApplication that runs as a server in the background, the syslog_daemon.

After it has been started during the system's boot process, it will just sit there and wait for messages. Every call to syslog() or log_thread/team() will pass a message to the server containing information about what should be written to the log and with what options. The message is not a BMessage, but a plain data structure that can be created without any knowledge about BMessages. That is needed, because the service is used by the kernel as well.

The server then just passes on that message to its internal handlers. It has two built-in handlers. One of them just processes the message and dumps a formatted text to the syslog file at /var/log/syslog. The other one creates a standard BMessage out of the message and broadcasts it to all of its listeners. However, how you can communicate with the syslog_daemon to get those messages will be the topic of another newsletter article.

If the syslog file reaches a certain size (512 kB), it will be renamed to syslog.old, and a new syslog file is created.

Using the system logger

As already mentioned, the system logging capabilities are accessible via the standard POSIX functions. Therefore, the syslog.h header is placed in the headers/posix directory, and the functions are implemented in libroot.so. That's already different from standard BeOS where you need to link against libbe.so to access that functionality. The syslog.h header can be found in the headers/be/support directory on a standard BeOS system.
The implementation and header have been moved to simplify porting of POSIX-compliant applications; however, that neither breaks binary nor source compatibility (as long as you haven't used "#include <support/syslog.h>" for your native Be apps.)

Logging sessions

The first call of a function that will connect to the syslog service will create a syslog session. It's important to know that there is one session for each thread that uses the service, as well as one extra session for all team-wide logging functions.

The original POSIX API as well as part of the additional BeOS API both use thread specific sessions. When a session is started, it will inherit the options defined for the team session. That means you can set logging options that every thread in your application will respect (if you don't overwrite them locally). But in order to define team wide options, you have to specifically use the BeOS-specific team API.

Team functions

  • void openlog_team(const char *ident, int logopt, int facility)

    Sets the team logging options for the other team functions and for inherited sessions.

    • ident is the identification string that prepends every message from your team.
    • logopt allows you to set several logging options (see below).
    • facility determines from what facility your message has been sent; for your standard issues, this should just be LOG_USER.

  • void closelog_team(void)

    Closes the current session. This has currently no effect for the team logging functions.

  • void log_team(int priority, const char *message, ...)

    Sends a message of the specified priority to the syslog daemon.

  • int setlogmask_team(int priorityMask)

    Use the LOG_MASK() macro to build a mask of priorities to show. All messages of other priorities will be discarded. Example uses:

      setlogmask_team(LOG_MASK(LOG_WARNING));
    // all messages of priority LOG_WARNING will be shown
      setlogmask_team(LOG_MASK(LOG_ERR + 1) - 1);
    // all messages with a priority level higher than LOG_ERR will be shown

Thread functions

The POSIX API and the thread specific Be API behave exactly in the same way; the *_thread() functions just clobber the global namespace :). All calls except for the closelog() calls will start a new session if there is none yet, and will inherit the current team logging options if they do.
  • void openlog_thread(const char *ident, int logopt, int facility)
    void openlog(const char *ident, int logopt, int facility)

    Sets the log options for the current thread.

  • void closelog_thread(void)
    void closelog(void)

    Closes the thread session, and frees all associated data. The next call to the syslog service will start a new session, and will inherit the team log options at that point again.

  • void log_thread(int priority, const char *message, ...)
    syslog(int priority, const char *message, ...)

    Sends a message of the specified priority to the syslog daemon.

  • int setlogmask_thread(int priorityMask)
    setlogmask(int priorityMask)

    Use the LOG_MASK() macro to build a mask of priorities to show. All messages of other priorities will be discarded.

Logging options for openlog()

These are the options that can be passed to openlog()/openlog_thread()/openlog_team(). Note, its effects might be depending on the syslog listener; for example, for a GUI syslog viewer, LOG_PID might have no effect at all.
  • LOG_PID
    log the process (thread/team) ID with each message
  • LOG_CONS
    if the message cannot be delivered to the syslog daemon, it will be directly dumped to stderr.
  • LOG_PERROR the message will not only be sent to the syslog daemon, it will also be written to the application's stderr, not only if sending fails like LOG_CONS.
There are some more flags defined, but they have currently no effect (notably, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT and LOG_SERIAL).

Playing with the OpenBeOS implementation

The server is implemented in current/src/servers/syslog_daemon, naturally, you have to build and start it, before it'll work - although you can also check out the syslog functionality without a living server.

To test the syslog functionality, you can use the provided test program. You'll find it in current/src/tests/kernel/libroot/posix/SyslogTest.cpp. Edit it as you please, and you'll get a good idea of how it works.

Differences between the OpenBeOS and the BeOS implementations

As already written some paragraphs above, the implemenation has been moved from libbe.so to libroot.so. But since all applications are linked against libroot.so anyway, this won't have any impact on binary compatibility.

The header file syslog.h has been moved to the headers/posix directory, where all other POSIX headers reside. If you've previously used the full path of the old header ("#include <support/syslog.h>"), you might encounter errors when trying to compile your old code. The issue has not been finally decided on, but it probably won't change in the release version of our headers.

It has not been tested if the thread logging functions inherit their settings from the team session on R5 or not, and if this mechanism works similarly if it's in place.

The only other known difference is that our syslog_daemon implements a way to broadcast the messages to a listener application. But as I already said earlier, this will be the topic of another newsletter article. Also note that the actual implementation of that protocol has not been finalized yet and is probably subject to change; your shiny system logger viewer might need to be updated before we reach R1.

References

There is a brief introduction to the BeOS system logger at http://www.beatjapan.org/mirror/www.be.com/aboutbe/benewsletter/Issue61.html . You can also find a description of the standard POSIX syslog functions at http://www.opengroup.org/onlinepubs/007904975/functions/closelog.html .

 
The "virtualdrive" driver by Axel Dörfler  

When developing an operating system, there is a big amount of secondary tools and test applications involved. Sometimes, you will find surprisingly useful things in this "cruft".

I want to introduce you to one of these gems today, the virtualdrive driver. You can find it in current/src/tests/kits/storage/virtualdrive in our repository. It has been developed mainly by Marcus Overhagen and Ingo Weinhold. I only made some minor changes to make it more useful and dangerous for developing the boot loader code.

It's probably only useful for some of you, and therefore we haven't yet put the work into it and published it separately from our project. Also, it won't be needed in OpenBeOS anymore, anyway.

So, what does it good for me?

The driver only does one little thing: it allows device-like access to a file. The main reason it has been developed was to test our partition scanner. You can use complete hard drive images with that driver.

If you are using Bochs (there are several entries in BeBits, the most recent one of them is (currently) http://www.bebits.com/app/3324) to run other operating systems (or OpenBeOS), you will notice that it is not able to access your devices directly, but needs every hard disk as a file.

With this driver and its accompanied mkvirtualdrive application, you can make the partitions on these files directly accessible to BeOS, and just mount them.

Installation

To install the driver to your local hard drive, you have to build it like this:

 
        $ jam install_virtualdrive 
        $ rescan virtualdrive 
        

To build the mkvirtualdrive tool, just type jam and then move the executable (somewhere below the distro-tree; jam will print out its exact location) to a place where you find it again, most probably you want to put it somewhere in your path, too, so /boot/home/config/bin is most appropriate for it.

For your convenience, I built a package that contains the driver and its controlling application--download it from our server.

How can I use it?

To avoid unwanted interactions with Tracker and other BeOS applications, the driver publishes its devices under /dev/misc/virtualdrive/. That makes its usage a bit more complicated than you'd want for the general end-user application.

Anyway, here is a step-by-step description of how to get it to work:

 
        $ mkvirtualdrive --install myHD.image 
        

This will print out the device under which you can now access the file. Note, the file is no longer accessible directly. If you are issuing the above command for the first time, you will probably get "/dev/misc/virtualdrive/0" back.

The file is now accessible through the device, but the BeOS disk system still doesn't take notice. If you want to mount the partitions on that image, or even want to create new partitions on that image, format it with another file system or whatever, you need to "connect" it to the system; you need to make a new "raw" entry somewhere below /dev/disk/. I choose the /dev/disk/virtual/files directory for that.

 
        $ mkdir -p /dev/disk/virtual/files/0 
        $ ln -s /dev/misc/virtualdrive/0 /dev/disk/virtual/files/0/raw 
        

Now, DriveSetup will suddenly notice the new "disk," and the shell command mountvolume will work on it as well. Unfortunately, Tracker will ignore the new disk in its mount menu, but it will show the partition's contents once you've mounted them; partitions on that disk will have a blue cabinet icon in Tracker (if they don't have their own icon).

If you have a volume called "BeOS" on a partition on that disk, you can mount it like this:

 
        $ mountvolume BeOS 
        

You can use the "-l" option to print out all mountable partitions; the partitions on the new disk are visible there as well.

Advanced features

That's nice, right? But as mentioned already, the file cannot be accessed anymore--the driver locks the file for exclusive access. If you want to use the file in Bochs again (or have a look at its contents with DiskProbe when you are developing a new partitioning system add-on), you need to unregister the file with the driver again.

Normally, you would just use

 
        $ mkvirtualvolume --uninstall /dev/misc/virtualdrive/0 
        
to achieve that. But unfortunately, once you've introduced the device to the BeOS disk system (by making the symlink and using mountvolume or DriveSetup on it), it won't close the device anymore, and therefore, the driver won't let other people access the file.

Note that you must unmount all mounted partitions from that file before you are doing the next step! You can tell the virtualdrive driver to close the file for some time and reestablish the connection later on. All accesses through the device will fail, so you should not use DriveSetup or mountvolume during that time:

 
        $ mkvirtualvolume --halt /dev/misc/virtualdrive/0 
        

The driver will close the file internally and allows others to access the file again. If you want to activate the device again (i.e. to mount it again), you just need to install it again like you did before:

 
        $ mkvirtualdrive --install myHD.image 
        

If nobody has closed the device in between and you haven't used the driver for other files in between, the file will be accessible through the device again. In order to let it work, you have to provide the exact same image with the exact same path to the "--install" call.

If you have forgotten which device points to what file, and which ones have been disabled and which haven't, you can use the following option of mkvirtualdrive to get that info:

 
        $ mkvirtualdrive --info /dev/misc/virtualdrive/0 
        

Disclaimer

Before you are using this driver in the way explained here, especially when you are using the features described under "Advanced features", you should make sure that you won't lose any important data on a sudden death.

We take no responsibility or liability on the effects of this software to your system. However, if you are careful and respect the warnings and directions given in this document, no case of failure or data loss is known to us. In any case, you've been warned. :-)

 
Total User Experience by Michael Phipps 

My first conception of BeOS was probably a little different than that of most of you. When I first learned about BeOS, the BeBox had just premiered. I learned about BeOS from the BeBook on-line. This harkens back to the Old Days of computer science, when you wrote your program on paper, tested it by hand (desk checking) until you were sure that it was right, then submitted it to the computer for a batch job. Because I was not in a rush to find the object/method that I needed, I could instead focus on just enjoying the beauty of the design. It was a very pleasant experience.

While I still like the API very much, it is not what most people see when they use an operating system. Most people's perspectives on an operating system come from a very few components--installation, booting, the "desktop", and the applications. I believe that the philosophy that Be had for each piece of the operating system was something that they called "the Right Way." I call it TUE--Total User Experience. Why the change in nomenclature? I believe that it is very easy for engineers, sometimes, to forget who our "real" customers are.

I suppose, then, that I should define who our "customers" are. There are many people who would like a piece of our efforts. I have heard from people who want to make OBOS the next server OS. Other people have said that it should be a great embedded OS. Yet others think that a platform for massive scientific computing makes sense. My consistent answer is that we should be the "Desktop OS." Some argue that we should stick with one of the last focuses of Be, Inc. and be the "Media OS." I am not opposed to being the "Media OS"; in fact, I believe that the two go hand in hand. Media, meaning video and sound, is inherent in the desktop. Ever since the multimedia hype of the mid-1990's when x86 users found themselves capable of handling CD-quality sound and TV-quality graphics. Who would run a desktop OS that doesn't play movies? Or one where they couldn't play MP3's (like I am right now)? No one. Media is a subset of desktop. Desktop is, of course, different from server, embedded (to some degree), and other platforms.

With our "customers" thus defined let's take a "TUE", then look at each of the most visible parts of BeOS and talk a bit about what was done right and wrong.

Jean-Louis Gassee once said that Be looked at the price/performance curve and chose the "sweet spot". This was in regard, if I remember correctly, to choosing dual PPC 603s for the BeBox. What does it mean? There is frequently a trade off between two aspects of an engineering decision; usually if you plot them on a graph, it is exponential--the graph transitions from incremental increases in price providing massive performance to massive increases in price providing incremental performance. Processors still do this today. I believe that this particular philosophy is very much the embodiment of TUE. With nearly every place you can point out something bad about an operating system, it will be because a poor point on the graph is chosen. Windows takes forever to install and boot? Look and see how many devices are supported. If we support 1/10 of the devices, we can boot 25X faster, or something on that order. Choosing the right devices is the tricky part. That is the mastery of TUE--that it works exceptionally well for 90% of users and can be made to work with little effort for the other 10%. It is possible to build a system that works faster/better (think custom kernel builds with all hardware support compiled in) or one the supports more users (think Windows), but the sweet spot is somewhere in between.

TUE is about making the user's experience so great that they beg for more, not mercy. TUE is about building something that you are proud of and proud to be associated with, not something that has to hide behind press releases and excuses. TUE is about choosing what to do, then doing it the way that is the best trade off you can make. TUE is about cautious experimentation. Never just dump radical changes on the consumer without massive in-house and beta testing. Look at the trouble that Apple has had with users adopting OS X (and, for that matter, Microsoft with WinXP). On the contrary, Microsoft is not making a peep over the "leaked" screenshots from Longhorn. They have hundreds of real life criticisms years before it ships.

The BeOS install is nearly optimal, as far as I can see. You can choose which partition you want and click Begin. That is the some total of the information that it needs to decide to install. No time zones, nothing else. The "More Options", which allows you to set up disk partitions is likewise very well done. There are a few changes that could be made in the partition tool, though. Specifically, it doesn't tell you the hard disk name. You only find out the BeOS /dev path (marginally useful) and the total disk size. I know that the BIOS, at the very least, knows more than that. If the BIOS can know the disk manufacturer, we should be able to find it. Secondly, a minor nit, the grid control doesn't have resizable columns. Finally, obviously unusable choices (floppy and CD-ROM) are listed. Still, all in all, this is the best installer that I have ever seen.

Booting is another excellent experience within BeOS. The speed is still legendary and unmatched. Speed, while a component of TUE, is not the most important part. The boot loader is graphically helpful, showing what hardware that it has finished initializing, where in the boot process it is and giving you useful feedback instead of just a progress bar. Additionally, you can hit space bar and get all sorts of options for booting. Finally, and probably best of all, the system matches all of your hardware every time at runtime. That means that if you pull a HD out to boot somewhere else, it will *just work* assuming that you have drivers.

Tracker, in many ways, is not much different than other desktop environments. The power of attributes and their flexible use is well-documented elsewhere. Replicants are different than the system tray that Windows offers. But, really, Tracker is very much like "everyone else"--there are icons on the desktop, folders can open, etc. Deskbar is not drastically better than the Start Menu from Windows. The desktop is an area where I have seen many complaints about the paradigm but few realistic choices.

Finally, we have applications. BeOS offers many standard controls and a standard look. This is somewhat different from the *NIXes. Windows and MacOS have a definite edge here in terms of numbers and types of controls. I would like to address this in the future (R2 or beyond), as I believe that some of these would be very useful to OBOS application designers.

BeOS, while not perfect, works very hard to do the things that it does "the Right Way". That is the tradition that we hope to carry on.