Versuch einer Mount-Automatik

Das Original Benutzerinterface Neutrino-SD incl. zapit, sectionsd, yWeb etc...
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Versuch einer Mount-Automatik

Beitrag von chkbox »

Ich habe mal versucht, den Schreibfehler bei Direktaufnahmen abzufangen. Ich probiere dann die Liste der Mounts durch, ob ihr mount Verzeichnis zum Aufnahmeverzeichnis passt und versuche dann es zu mounten. Bei mir klappt es so weit ganz gut. Vielleicht kann ja mal jemand von den erfahrenen Programmierern hier nachsehen, ob das so halbwegs brauchbar ist.

Hintergrund: Ich habe mehrere Server, die abwechselnd mal laufen und den Stream aufnehmen und suchte nach einer Automatik, die das Aufnahmeverzeichnis einem verfügbaren Server zuordnet. Irgendwie habe ich dafür kein normales Linux-Tool gefunden (Oder ich bin mal wieder an meinen Linux Kenntnissen gescheitert)

Code: Alles auswählen

--- stream2file.cpp.orig	2004-08-05 00:23:53.015625000 +0200
+++ stream2file.cpp	2004-08-05 00:34:24.859375000 +0200
@@ -34,6 +34,10 @@
 
 #include <stream2file.h>
 
+#include <global.h>
+#include "../gui/nfs.h"
+#include <sys/mount.h>
+
 #include <eventserver.h>
 #include <neutrinoMessages.h>
 
@@ -430,16 +434,40 @@
 
 	// write stream information (should wakeup the disk from standby, too)
 	sprintf(buf, "%s.xml", filename);
-	if ((fd = open(buf, O_SYNC | O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0)
-	{
-		write(fd, info, strlen(info));
-		fdatasync(fd);
-		close(fd);
-	}
-	else
+	
+	for(int i = 0; i <= 4; i++)
 	{
-		DEC_BUSY_COUNT
-		return STREAM2FILE_INVALID_DIRECTORY;
+		if ((fd = open(buf, O_SYNC | O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0)
+		{
+			write(fd, info, strlen(info));
+			fdatasync(fd);
+			close(fd);
+			break;
+		}
+		else
+			printf("[record] %d. try failed: Can't write to directory\n", i);
+		
+		if(i == 4)
+		{
+			DEC_BUSY_COUNT
+			return STREAM2FILE_INVALID_DIRECTORY;
+		}
+		
+		if (strlen(g_settings.network_nfs_ip[i].c_str()) == 0 ||
+			strlen(g_settings.network_nfs_dir[i]) == 0 ||
+			strlen(g_settings.network_nfs_local_dir[i]) == 0)
+			continue;
+		
+		if(strncmp(buf, g_settings.network_nfs_local_dir[i], strlen(g_settings.network_nfs_local_dir[i])) == 0)
+		{
+			printf("remount %s to %s:%s\n", g_settings.network_nfs_local_dir[i], g_settings.network_nfs_ip[i].c_str(), g_settings.network_nfs_dir[i]);
+			
+			umount2(g_settings.network_nfs_local_dir[i],MNT_FORCE);
+			
+			CNFSMountGui::mount(g_settings.network_nfs_ip[i].c_str(), g_settings.network_nfs_dir[i], g_settings.network_nfs_local_dir[i], 
+					(CNFSMountGui::FSType) g_settings.network_nfs_type[i], g_settings.network_nfs_username[i], 
+					g_settings.network_nfs_password[i], false);
+		}
 	}
 
 	if (splitsize < TS_SIZE)
*edit: Bei Neutriono passt es besser
thegoodguy
Erleuchteter
Erleuchteter
Beiträge: 465
Registriert: Mittwoch 14. August 2002, 20:45

Beitrag von thegoodguy »

Hmmm, also ich haette folgende Anmerkungen:
1.) statt stream2file.cpp sollte eher vcrcontrol.cpp modifiziert werden, weil stream2file bislang von der GUI nix mitbekommt um nicht alles total ineinander zu verwurschteln.
2.) Falls der mount-point in /var liegt (writeable bereich), so wird das .xml einfach ins flash geschrieben und dann trotzdem nichts gemountet.
3.) Nach allen Aufnahmen sollten nicht mehr benoetigte mounts umounted werden.
4.) So wie es eine Option "bei starten mounten" gibt, koennte es auch bei jedem mount eine option "bei directrecording mounten + unmounten" geben.

Patches welcome.
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

thegoodguy hat geschrieben:1.) statt stream2file.cpp sollte eher vcrcontrol.cpp modifiziert werden, weil stream2file bislang von der GUI nix mitbekommt um nicht alles total ineinander zu verwurschteln.
Werde ich mal versuchen.
thegoodguy hat geschrieben:2.) Falls der mount-point in /var liegt (writeable bereich), so wird das .xml einfach ins flash geschrieben und dann trotzdem nichts gemountet.
Stimmt, aber das ist jetzt auch so und ich will nicht wissen wie lange der Stream ins Flash passt. Außerdem habe ich keine Ahnung wie ich den Flash vom rw mounts unterscheiden soll.
thegoodguy hat geschrieben:3.) Nach allen Aufnahmen sollten nicht mehr benoetigte mounts umounted werden.
Wäre auch noch eine Erweiterung.
Allerdings hatte ich das so gedacht, dass bei Start ein Verzeichnis gemountet wird und wenn dieses ausfällt, ein Ersatz gemountet wird, der wiederum so lange bleibt, bis er ausfällt. Ist vielleicht etwas weniger schön, weil man nie so ganz genau weiß, auf welchem Server man ist.
Ich finde es aber OK, denn man kann ja noch zusätzliche mounts in anderen Verzeichnissen erzeugen, die nicht vom Aufnehmen verändert werden.
thegoodguy hat geschrieben:4.) So wie es eine Option "bei starten mounten" gibt, koennte es auch bei jedem mount eine option "bei directrecording mounten + unmounten" geben.
Nette Idee, aber das Überschreitet meine Fähigkeiten im Moment doch erheblich.
essu
Tuxboxer
Tuxboxer
Beiträge: 2452
Registriert: Montag 21. Oktober 2002, 10:04

Beitrag von essu »

chkbox hat geschrieben:
thegoodguy hat geschrieben:4.) So wie es eine Option "bei starten mounten" gibt, koennte es auch bei jedem mount eine option "bei directrecording mounten + unmounten" geben.
Nette Idee, aber das Überschreitet meine Fähigkeiten im Moment doch erheblich.

Code: Alles auswählen

thegoodguy    04/08/02 15:01:29

  Modified:    tuxbox/neutrino/src neutrino.cpp
  Log:
  execute CONFIGDIR "/recording.end" script if recording ends
  
  Revision  Changes    Path
  1.708     +12 -3     apps/tuxbox/neutrino/src/neutrino.cpp
So eine Prioritätenliste beim Mounten, ala wenn das verfügbar, dann mounte das, wenn nicht, dann jenes etc. fände ich auch gut.
Schon gelesen ???
ENIGMA-DOC
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

essu hat geschrieben:
chkbox hat geschrieben:
thegoodguy hat geschrieben:4.) So wie es eine Option "bei starten mounten" gibt, koennte es auch bei jedem mount eine option "bei directrecording mounten + unmounten" geben.
Nette Idee, aber das Überschreitet meine Fähigkeiten im Moment doch erheblich.

Code: Alles auswählen

thegoodguy    04/08/02 15:01:29

  Modified:    tuxbox/neutrino/src neutrino.cpp
  Log:
  execute CONFIGDIR "/recording.end" script if recording ends
  
  Revision  Changes    Path
  1.708     +12 -3     apps/tuxbox/neutrino/src/neutrino.cpp
Sorry, aber ich verstehe nicht ganz, was dies miteinander zu tun hat. Ich hatte das so verstanden, das thegoodguy meinte, dass es eine neue Option im GUI geben soll und das ist wie gesagt für mich zu schwer.
essu
Tuxboxer
Tuxboxer
Beiträge: 2452
Registriert: Montag 21. Oktober 2002, 10:04

Beitrag von essu »

chkbox hat geschrieben:Sorry, aber ich verstehe nicht ganz, was dies miteinander zu tun hat. Ich hatte das so verstanden, das thegoodguy meinte, dass es eine neue Option im GUI geben soll und das ist wie gesagt für mich zu schwer.
Naja, dieses recording.end-Script könnte zum umount benutzt werden und analog könnte es ein recording.start-Script geben, wenn diesen scripten auch noch der Name der aufgenommenen/aufzunehmenden Datei übergeben werden könnte, wären noch viele weiter Features denkbar.
Schon gelesen ???
ENIGMA-DOC
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

OK, das macht Sinn. Wenn man den Dateinamen im Script hätte könnte man auch noch solche Sachen wie genpsi automatisch ausführen machen.
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

thegoodguy hat geschrieben:1.) statt stream2file.cpp sollte eher vcrcontrol.cpp modifiziert werden, weil stream2file bislang von der GUI nix mitbekommt um nicht alles total ineinander zu verwurschteln.
Habe ich jetzt umgebaut. Code ist aber fast unverändert und ich habe auch nur ein Include gespart, aber dein Argument ist sicherlich richtig.

Code: Alles auswählen

--- vcrcontrol.cpp.orig	2004-08-04 15:01:28.343750000 +0200
+++ vcrcontrol.cpp	2004-08-06 13:12:02.234375000 +0200
@@ -62,6 +62,10 @@
 #include <daemonc/remotecontrol.h>
 #include <zapit/client/zapittools.h>
 
+//for automounter
+#include <sys/mount.h>
+#include "../gui/nfs.h"
+
 extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */
 
 
@@ -568,13 +572,49 @@
 	time_t t = time(NULL);
 	strftime(&(filename[pos]), sizeof(filename) - pos - 1, "%Y%m%d_%H%M%S", localtime(&t));
 
-	stream2file_error_msg_t error_msg = ::start_recording(filename,
+	stream2file_error_msg_t error_msg;
+	for(int i = 0; i <= 4; i++)
+	{
+		error_msg = ::start_recording(filename,
 							      getCommandString(CMD_VCR_RECORD, channel_id, epgid, apids).c_str(),
 							      Use_O_Sync,
 							      ((unsigned long long)SplitSize) * 1048576ULL,
 							      numpids,
 							      pids,
 							      g_settings.misc_option[MISC_SETTING_SPTS_MODE]);
+		
+		// track error
+		if (error_msg != STREAM2FILE_INVALID_DIRECTORY)
+			break;
+		
+		printf("[record] %d. try failed: Can't write to directory (%s)\n", i, filename);
+		
+		// no more mount entries in GUI -> end this
+		if(i == 4)
+			break;
+		
+		// skip if empty
+		if (strlen(g_settings.network_nfs_ip[i].c_str()) == 0 ||
+			strlen(g_settings.network_nfs_dir[i]) == 0 ||
+			strlen(g_settings.network_nfs_local_dir[i]) == 0)
+			i++;
+		
+		// recheck for end of mount entries in GUI
+		if(i == 4)
+			break;
+		
+		// this unmount, then mount
+		if(strncmp(filename, g_settings.network_nfs_local_dir[i], strlen(g_settings.network_nfs_local_dir[i])) == 0)
+		{
+			printf("remount %s to %s:%s\n", g_settings.network_nfs_local_dir[i], g_settings.network_nfs_ip[i].c_str(), g_settings.network_nfs_dir[i]);
+			
+			umount2(g_settings.network_nfs_local_dir[i],MNT_FORCE);
+			
+			CNFSMountGui::mount(g_settings.network_nfs_ip[i].c_str(), g_settings.network_nfs_dir[i], g_settings.network_nfs_local_dir[i], 
+					(CNFSMountGui::FSType) g_settings.network_nfs_type[i], g_settings.network_nfs_username[i], 
+					g_settings.network_nfs_password[i], false);
+		}
+	}
 
 	if (error_msg == STREAM2FILE_OK)
 	{
Zu den anderen Sachen muss ich leider sagen, dass ich nicht unbedingt eine Verwendung dafür habe und mir fällt entweder keine Lösung ein oder ich habe momentan nicht genug Zeit. Vielleicht kann weiß jemand anders was schönes dafür...
essu hat geschrieben:So eine Prioritätenliste beim Mounten, ala wenn das verfügbar, dann mounte das, wenn nicht, dann jenes etc. fände ich auch gut.
Direkt geht das halt auch mit diesen Änderungen nicht, aber da sie die mount Liste von oben nach unten abarbeiten, erreichst du diesen Effekt durch eine entsprechende Anordnung dort.
essu
Tuxboxer
Tuxboxer
Beiträge: 2452
Registriert: Montag 21. Oktober 2002, 10:04

Beitrag von essu »

chkbox hat geschrieben:OK, das macht Sinn. Wenn man den Dateinamen im Script hätte könnte man auch noch solche Sachen wie genpsi automatisch ausführen machen.
Quick `n e dirty /var/tuxbox/config/recording.end:

Code: Alles auswählen

#!/bin/sh
RECDIR=/hdd/movie
cd $RECDIR && FILES=`ls -c *.ts` || exit
for FILE in $FILES; do
 break;
done
dbox2genpsi $RECDIR/$FILE

Schon gelesen ???
ENIGMA-DOC
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

Interpretiere ich das richtig, dass dieses Script immer die erste Datei bearbeitet? Wäre halt blöd, wenn man mehrere Aufnahmen macht.
essu
Tuxboxer
Tuxboxer
Beiträge: 2452
Registriert: Montag 21. Oktober 2002, 10:04

Beitrag von essu »

chkbox hat geschrieben:Interpretiere ich das richtig, dass dieses Script immer die erste Datei bearbeitet? Wäre halt blöd, wenn man mehrere Aufnahmen macht.
Immer die zuletzt aufgenommene (nach Timestamp), da recording.end nach jeder Aufnahme ausgeführt wird, sollten schliesslich alle Dateien gepatched sein, wie gesagt, es ist quick`n edirty, das Aufnahmeverzeichnis muss von Handeingegeben werden, eleganter wäre es natürlich, wenn der Dateiname inkl. Pfad an das Script übergeben werden könnte.

BTW: recording.start dürften ein paar Zeilen sein in der Art:

Code: Alles auswählen

#define NEUTRINO_RECORDING_ENDED_SCRIPT CONFIGDIR "/recording.end"
+#define NEUTRINO_RECORDING_STARTING_SCRIPT CONFIGDIR +"/recording.start"
#define NEUTRINO_SCAN_SETTINGS_FILE     CONFIGDIR "/scan.conf"
nextRecordingInfo = (CTimerd::RecordingInfo *) data;

+		if (system(NEUTRINO_RECORDING_STARTING_SCRIPT) != 0)
+		{
+		    perror(NEUTRINO_RECORDING_STARTING_SCRIPT "failed");}
+		else	
+		{
+		    puts("[neutrino.cpp] executing " NEUTRINO_RECORDING_STARTING_SCRIPT ".");	
+		}
+
		startNextRecording();
Schon gelesen ???
ENIGMA-DOC
chkbox
Erleuchteter
Erleuchteter
Beiträge: 440
Registriert: Samstag 10. April 2004, 15:17

Beitrag von chkbox »

Ich habe es nicht so drauf mit Linux Scripten, aber könnte es sein, dass man dann Probleme mit dem Filesplitting bekommt? Dort wäre dann ja der zweite Teil der letzte erzeugte, darf aber nicht bearbeitet werden weil sonst Frames fehlen.
essu
Tuxboxer
Tuxboxer
Beiträge: 2452
Registriert: Montag 21. Oktober 2002, 10:04

Beitrag von essu »

chkbox hat geschrieben:[...] aber könnte es sein, dass man dann Probleme mit dem Filesplitting bekommt? Dort wäre dann ja der zweite Teil der letzte erzeugte, darf aber nicht bearbeitet werden weil sonst Frames fehlen.
...könnte sein, ich hab mir das handling nicht näher angeschaut, aber das shell-script entsprechend zu ändern (es nur auszuführen, wenn es *.001.ts ist) wäre eine der leichteren Übungen

--edit: --

Ist jetzt so geändert, dass nur *.001.ts gepatched wird:

Code: Alles auswählen

#!/bin/sh
# $Id: recording.end,v 1.6 2004/08/11 08:52:35 essu Exp $
FOUND=`grep network_nfs_recordingdir /var/tuxbox/config/neutrino.conf` || exit
RECDIR=`expr substr $FOUND 26 154`
cd $RECDIR && FILES=`ls -c *.001.ts` || exit
for WORD in $FILES; do
 FILE=$FILE" "$WORD
 if [ $( expr index $WORD "." ) -gt 0 ]; then
  break;
 fi
done
dbox2genpsi $RECDIR/$FILE
Schon gelesen ???
ENIGMA-DOC