Printk behaviour change with early_printk enabled - linux

Normally printk does not print any messages before console_init which is present in start_kernel. But with early_printk enabled, printk starts printing messages before console initialization. Now how does this behaviour of printk change since I am still using printk function to print debug messages and not early_printk function. How is this mapping done?

It's not really a mapping. When early_printk is enabled, the same printk() is used as before, just new boot console is being registered in that case, and printk() uses it on early boot stages.
Look at arch/arm/kernel/early_printk.c. You can see that:
new console being registered with register_console() function
that console has CON_BOOT flag, so it's unregistered automatically as soon as real console is registered
printing happens via early_write() function, which in turn uses printch() function, which implemented for each platform separately
Where in kernel source the early_console is disabled after kernel console initialization?
It's done in register_console() function:
if (bcon &&
((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
!keep_bootcon) {
/* We need to iterate through all boot consoles, to make
* sure we print everything out, before we unregister them.
*/
for_each_console(bcon)
if (bcon->flags & CON_BOOT)
unregister_console(bcon);
}
All boot consoles are disabled by unregister_console() function in code above (when real console is being registered).
And where is the real console getting registered?
Real consoles use the same method for registration -- register_console() function. For example:
from my board's defconfig file (arch/arm/configs/omap2plus_defconfig) I can see that my board is using CONFIG_SERIAL_8250 as real console
we can search where register_console() is executed in my serial driver; it's done in univ8250_console_init() function
Is there any way to keep boot consoles up after console initialization and disable real console?
Boot consoles are automatically unregistered only when real console is registered. Following this logic, you just need to disable the real console in order to keep boot console intact.
So what you need to do, is to find out which exactly driver is used for real console in your case. You can do that looking into your .config file, or the *_defconfig file for your board. Once you located it, just disable that driver in configuration and rebuild the kernel.
If after doing so you keep observing the registering of some real console, you need to add some debug printings to register_console(), to figure out what driver is being registered, and then disable it in your configuration.

Related

zbus connection not displayed in busctl list

I'm using the zbus crate to make a server able to get events from the dbus.
It works well my code (basically the same as the example from the documentation) is able to receive events so it's fine.
I use busctl to send an event like in the example:
busctl --user call org.zbus.MyGreeter /org/zbus/MyGreeter org.zbus.MyGreeter1 SayHello s "Maria"
And my code is able to receive the event with the parameter just fine.
The thing is I'm having some issues with udev and while I was trying to fix it I found some weird things:
If I send an event with another user it fails with Call failed: the name org.zbus.MyGreeter was not provided by any .service files while my program is running
When I do busctl list --acquired I don't see org.zbus.MyGreeter in the result
My question is: is it normal my program does not appear in the busctl list? Am I doing something wrong or do I use the wrong library to do what I want to do?
Ok it seems there are 2 busses and I was not using the system bus.
I had to replace the method session to system to indicates I want my program to run on the system bus.
Like this:
let _ = ConnectionBuilder::system()?
.name("org.zbus.MyGreeter")?
.serve_at("/org/zbus/MyGreeter", greeter)?
.build()
.await?;
Doing this is not enough because my program does not have to permission to create a service on the bus system. So I had to create a file in /usr/share/dbus-1/system.d where I did write the configuration needed.

QFileSystemWatcher file changed signal emits only ones for few file update

I am using QFileSystemWatcher to control the log file changes.
For creating and updating the log file I am using boost library.
When I log few messages in one method file changing signal emits only ones (for last message), but I see that file updating every time after log message added.
So, the code for QFileSystemWatcher is
std::string fn = "app.log";
logging::init_log(fn);
QFileSystemWatcher* watcher = new QFileSystemWatcher();
auto success = QObject::connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(handleFileChanged(QString)));
Q_ASSERT(success);
watcher->addPath(QString::fromStdString(fn));
adding log messages
void a(){
/* some code */
logging::write_log("test error", logging::kError);
logging::write_log("test info", logging::kInfo);
}
QFileSystemWatcher emits signal only ones for Info level message.
In file manager I see that file updating after each call (test error, test info).
In log file initialization I use
sink->locked_backend()->auto_flush(true);
so the file updates immediately.
How can I fix this? Or maybe there is another approach how to handle log file updating to show message in GUI.
Similar filesystem event notifications are usually collapsed into one, unless they are consumed by a reader. For example, if the writer writes 10 bytes to a file, the thread that monitors that file for writes will typically see one event instead of 10. This is explicitly outlined in inotify description notes on Linux, which is likely used internally by QFileSystemWatcher.
This should not matter for any correct implementation of a filesystem monitoring software. The notification only allows the monitor to notice that some event happened (e.g. a write occurred), and it is up to the software to discover further details about the event (e.g. the amount of data that was written, and writing position).
If you aim to just display the written logs, you should be able to just read the file contents from the current reading position to the end of the file. That read operation may return one log record or more. It can return an incomplete log record, too, if the C++ standard library is implemented in a certain way (e.g. when auto_flush is disabled, and the stream buffer fills the internal buffer with part of the log record content before issuing write). The monitoring software should parse the read content to separate log records and detect incomplete log records (e.g. split data by newline characters).

when use gpio_set_value, i can't get gpio state with gpio_get_value later

I'm learning how to setup key-interrupt with generic gpio. But there is problem that i can't understand what's wrong with my code.
gpio_is_valid(mygpio);
gpio_request(mygpio);
gpio_direction_output(……);
……
It's simple setting with the gpio-pin. Then I register an interrupt handler.In interrupt handler, I use the tasklet.
BUT! Strange thing happened! As follow:
gpio_set_value(mygpio, 1);
considered about that the hardware need time to run and set, so even I insert mdelay(100) here. After that invoke gpio_get_value(mygpio), the return is 0, zero!!!
At last, I disabled all interrupt and do above again.But nothing has changed. What's wrong happened??

hunchentoot-based app in a lisp image (from buildapp) immediately returns

So I have an application using restas, based on hunchentoot.
At some point, I have the following function:
(defun main (args)
(declare (ignore args))
(set-config)
(restas:start '#:spa :port 8080))
(set-config) sets a few values related to database.
Anyway, I then use buildapp in the following way:
buildapp --output dist/spa --load-system spa --asdf-tree ~/quicklisp/ --entry spa::main --compress-core
Which works perfectly. The (set-config) function requires a config.json file to be present, and it indeed doesn't work when the file doesn't exist, so I know for sure that the application is correctly compiled.
When I run the generated binary however, the application immediately returns. Which means the HTTP server doesn't stay up.
I guess it's related to the fact that hunchentoot spawns a new thread, but it shouldn't stop the process, should it?
Also, I don't want to not use threads, i.e. I want the fact that each request is a separate thread.
So... I'm not sure exactly why it immediately returns. Why? And how to fix it?
I guess that you have to enter a main loop to keep the program running. The example at http://www.xach.com/lisp/buildapp/ uses the SBCL-specific (sb-impl::toplevel-repl nil).

libspotify: logging out or releasing session causes crash

This is in response to dan's (dan^spotify on IRC) offer to take a look at my testcase, but I post it here in case anyone has encountered similar issues.
I'm experiencing a problem with libspotify where the application crashes (memory access violation) in both of these two scenarios:
the first sp_session_process_events (triggered by notify main thread callback) that's called after the sp_session_logout() function is called crashes the application
skipping logout and calling sp_session_release() crashes the application
I've applied sufficient synchronization from the session callbacks, and I'm otherwise operating on a single thread.
I've made a small testcase that does the following:
Creates session
Logs in
Waits 10 seconds
Attempts to logout, upon which it crashes (when calling sp_session_process_events())
If it were successful in logging out (which it isn't), would call sp_session_release()
I made a Gist for the testcase. It can be found here: https://gist.github.com/4496396
The test case is made using Qt (which is what I'm using for my project), so you'd need Qt 5 to compile it. I've also only written it with Windows and Linux in mind (don't have Mac). Assuming you have Qt 5 and Qt Creator installed, the instructions are as follows:
Download the gist
Copy the libspotify folder into the same folder as the .pro file
Copy your appkey.c file into the same folder
Edit main.cpp to login with your username and password
Edit line 38-39 in sessiontest.cpp and set the cache and settings path to your liking
Open up the .pro file and run from Qt Creator
I'd be very grateful if someone could tell me what I'm doing wrong, as I've spent so many hours trying anything I could think of or just staring at it, and I fear I've gone blind to my own mistakes by now.
I've tested it on both Windows 7 and Linux Ubuntu 12.10, and I've found some difference in behavior:
On Windows, the testcase crashes invariably regardless of settings and cache paths.
On Linux, if setting settings and cache to "" (empty string), logging out and releasing the session works fine.
On Linux, if paths are anything else, the first run (when folder does not already exist) logs out and releases session as it should, but on the next run (when folder already exists), it crashes in the exact same way as it does on Windows.
Also, I can report that sp_session_flush_caches() does not cause a crash.
EDIT: Also, hugo___ on IRC was kind enough to test it on OSX for me. He reported no crashes despite running the application several times in a row.
While you very well may be looking at a bug in libspotify, I'd like to point out a possibly redundant call to sp_session_process_events(), from what I gathered from looking at your code.
void SessionTest::processSpotifyEvents()
{
if (m_session == 0)
{
qDebug() << "Process: No session.";
return;
}
int interval = 0;
sp_session_process_events(m_session, &interval);
qDebug() << interval;
m_timerId = startTimer(interval);
}
It seems this code will pickup the interval value and start a timer on that to trigger a subsequent call to event(). However, this code will also call startTimer when interval is 0, which is strictly not necessary, or rather means that the app can go about doing other stuff until it gets a notify_main_thread callback. The docs on startTimer says "If interval is 0, then the timer event occurs once every time there are no more window system events to process.". I'm not sure what that means exactly but it seems like it can produce at least one redundant call to sp_session_process_events().
http://qt-project.org/doc/qt-4.8/qobject.html#startTimer
I notice that you will get a crash on sp_session_release if you have a track playing when you call it.
I have been chasing this issue today. Login/logout works just fine on Mac, but the issue was 100% repeatable as you described on Windows.
By registering empty callbacks for offline_status_updated and credentials_blob_updated, the crash went away. That was a pretty unsatisfying fix, and I wonder if any libspotify developers want to comment on it.
Callbacks registered in my app are:
logged_in
logged_out
notify_main_thread
log_message
offline_status_updated
credentials_blob_updated
I should explicitly point out that I did not try this on the code you supplied. It would be interesting to know if adding those two extra callbacks works for you. Note that the functions I supply do absolutely nothing. They just have to be there and be registered when you create the session.
Adding the following call in your "logged in" libspotify callback seems to fix this crash as detailed in this SO post:
sp_session_playlistcontainer(session);

Resources