Browse Source

Changelog and documentation for new daemon discovery files

tags/v1.6.0
Nils 3 years ago
parent
commit
1b3243edeb
5 changed files with 72 additions and 15 deletions
  1. +1
    -0
      CHANGELOG
  2. +16
    -2
      docs/api/index.html
  3. +1
    -1
      docs/index.html
  4. +13
    -1
      docs/src/api/index.adoc
  5. +41
    -11
      src/nsmd.cpp

+ 1
- 0
CHANGELOG View File

@@ -12,6 +12,7 @@ nsmd now follows the XDG Base Directory Specifications:
Lockfiles fixed (see issue #gh-31)
Lockfiles are now in $XDG_RUNTIME_DIR/nsm/
Lockfiles now each contain the session path, the osc NSM_URL and the nsmd PID
One daemon file for each currently running nsmd is created in $XDG_RUNTIME_DIR/nsm/d/ containing the osc url. This enables discovery of running daemons.
New section in the API documentation for the above.
Fixes and guards against trying to load non-existing sessions and creating new sessions under existing names



+ 16
- 2
docs/api/index.html View File

@@ -467,6 +467,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<ul class="sectlevel4">
<li><a href="#_subdirectories_hierarchical_structure">1.2.3.1. Subdirectories / Hierarchical Structure</a></li>
<li><a href="#_lockfiles">1.2.3.2. Lockfiles</a></li>
<li><a href="#_daemon_discovery">1.2.3.3. Daemon Discovery</a></li>
</ul>
</li>
</ul>
@@ -796,6 +797,19 @@ osc.udp://myuser.localdomain:11287/
</div>
</div>
</div>
<div class="sect4">
<h5 id="_daemon_discovery">1.2.3.3. Daemon Discovery</h5>
<div class="paragraph">
<p>Each running <code>nsmd</code>, per user, creates a state file under <code>$XDG_RUNTIME_DIR/nsm/d/</code> (usually
<code>/run/user/XXXX/nsm/d/</code>) that can be used to look up running daemons, even if no session is loaded.
The files contains the daemons osc.udp URL that is compatible with the --nsm-url parameter of the GUI.</p>
</div>
<div class="paragraph">
<p>This enables you to e.g. start nsmd at boot with a random free port. Server-control programs such
as GUIs can then use this to look for running servers without requiring the user to look up and
input an osc URL manually as command line parameter.</p>
</div>
</div>
</div>
</div>
</div>
@@ -1871,7 +1885,7 @@ behaviour more strictly as well, removing false session entries in 3rd party cli
<li>
<p>nsmd now follows the XDG Base Directory Specifications for it&#8217;s session root and lock files. This
if of no consequence to clients but required documentation nevertheless, which was described as
"background information" in the new section.</p>
"background information" in the chapters for lock files and daemon disovery.</p>
</li>
</ul>
</div>
@@ -1882,7 +1896,7 @@ if of no consequence to clients but required documentation nevertheless, which w
<div id="footer">
<div id="footer-text">
Version API 1.1.2<br>
Last updated 2022-03-05 12:34:04 +0100
Last updated 2022-03-15 18:44:44 +0100
</div>
</div>
</body>

+ 1
- 1
docs/index.html View File

@@ -557,7 +557,7 @@ Documentation and tutorials for software-developers will be added at a later dat
<div id="footer">
<div id="footer-text">
Version 1.6.0<br>
Last updated 2022-03-05 12:34:04 +0100
Last updated 2022-03-15 18:44:44 +0100
</div>
</div>
</body>

+ 13
- 1
docs/src/api/index.adoc View File

@@ -230,6 +230,18 @@ osc.udp://myuser.localdomain:11287/
3022
```

===== Daemon Discovery

Each running `nsmd`, per user, creates a state file under `$XDG_RUNTIME_DIR/nsm/d/` (usually
`/run/user/XXXX/nsm/d/`) that can be used to look up running daemons, even if no session is loaded.
The files contains the daemons osc.udp URL that is compatible with the --nsm-url parameter of the GUI.


This enables you to e.g. start nsmd at boot with a random free port. Server-control programs such
as GUIs can then use this to look for running servers without requiring the user to look up and
input an osc URL manually as command line parameter.


== NSM OSC Protocol

All message parameters are REQUIRED. All messages MUST be sent from the same socket as the `announce`
@@ -908,4 +920,4 @@ behaviour more strictly as well, removing false session entries in 3rd party cli

* nsmd now follows the XDG Base Directory Specifications for it's session root and lock files. This
if of no consequence to clients but required documentation nevertheless, which was described as
"background information" in the new section.
"background information" in the chapters for lock files and daemon disovery.

+ 41
- 11
src/nsmd.cpp View File

@@ -64,6 +64,7 @@ static int signal_fd;

static char *session_root;
static char *lockfile_directory;
static char *daemon_file;

#define NSM_API_VERSION_MAJOR 1
#define NSM_API_VERSION_MINOR 1
@@ -2584,6 +2585,10 @@ handle_signal_clean_exit ( int signal )
close_session();
free( session_root );
free( lockfile_directory );
unlink( daemon_file );
MESSAGE( "Deleted daemon file %s", daemon_file );
free( daemon_file );

exit(0);
}

@@ -2717,9 +2722,24 @@ int main(int argc, char *argv[])
}
}
MESSAGE( "Using %s for lock-files.", lockfile_directory );
}


//Now create another subdir for daemons .../nsm/d/ where each daemon has a port number file
char * daemon_directory;
asprintf( &daemon_directory, "%s/d", lockfile_directory);
struct stat st_daemonfile_dir_mkdir;
if ( stat( daemon_directory, &st_daemonfile_dir_mkdir ) )
{
if ( mkdir( daemon_directory, 0771 ) )
{
FATAL( "Failed to create daemon file directory %s with error: %s", daemon_directory, strerror( errno ) );
}
}
//daemon_file is a global var
asprintf( &daemon_file, "%s/%d", daemon_directory, getpid());
free ( daemon_directory );
MESSAGE( "Using %s as daemon file.", daemon_file );
//The actual daemon file will be written below after announcing the session url.
}

if ( !session_root ) {
/* The user gave no specific session directory. We use the default.
@@ -2736,6 +2756,7 @@ int main(int argc, char *argv[])
*/
struct stat st_session_root;

//TODO: Valgrind shows a memory leak for the next line. Why?
asprintf( &session_root, "%s/%s", getenv( "HOME" ), "NSM Sessions" );
if ( stat( session_root, &st_session_root ) == 0 && S_ISDIR(st_session_root.st_mode)) {
WARNING ( "An old session directory was detected in %s. You can continue to use it but it is recommended to move your sessions to $XDG_DATA_HOME/nsm-sessions/. If you don't know where that is simply rename your current session-directory and start nsmd, which will tell you the new directory.", session_root);
@@ -2775,7 +2796,20 @@ int main(int argc, char *argv[])
FATAL( "Failed to create OSC server." );
}

printf( "NSM_URL=%s\n", osc_server->url() );
char * url = osc_server->url();

printf( "NSM_URL=%s\n", url );

//Write the URL into the daemon_file that is named after our PID
FILE *fpdaemon = fopen( daemon_file, "w" );
if ( !fpdaemon ) {
FATAL( "Failed to write daemon file to %s with error: %s", daemon_file, strerror( errno ) );
}
fprintf( fpdaemon, "%s\n", url );
MESSAGE( "Created daemon file %s", daemon_file );
fclose( fpdaemon );

free( url );

if ( gui_url )
{
@@ -2847,24 +2881,20 @@ int main(int argc, char *argv[])
}

/* listen for sigchld signals and process OSC messages forever */
int start_pid = getppid(); //get parent pid
int start_ppid = getppid(); //get parent pid
for ( ;; )
{
wait( 1000 ); //1000 ms
//This still has some corner cases, like a race condition on startup that never gets the real PID, but
//we cover the majority of cases at least:
if ( start_pid != getppid() ) {
WARNING ( "Our parent PID changed from %d to %d, which indicates a possible GUI crash. The user has no control over the session anymore. Trying to shut down cleanly.", start_pid, getppid());
if ( start_ppid != getppid() ) {
WARNING ( "Our parent PID changed from %d to %d, which indicates a possible GUI crash. The user has no control over the session anymore. Trying to shut down cleanly.", start_ppid, getppid());
handle_signal_clean_exit ( 0 );
}
}

//Code after here will not be executed if nsmd is stopped with any abort-signal like SIGINT.
//Without a signal handler clients will remain active ("zombies") without nsmd as parent.
//MESSAGE ( "End of Program");

//free(session_root);// This was not executed if nsmd received a stop signal. It is now handled by handle_signal_clean_exit()
//osc_server->run();

//Therefore exit is handled by handle_signal_clean_exit()
return 0;
}

Loading…
Cancel
Save