Worked forth in order to make cdrskin fully newapi compliant

This commit is contained in:
Thomas Schmitt 2006-08-25 18:21:03 +00:00
parent 9063945d28
commit c9ad5997d0
1 changed files with 109 additions and 5 deletions

View File

@ -35,6 +35,51 @@ The implementation of an option would probably consist of
existing methods existing methods
See option blank= for an example. See option blank= for an example.
------------------------------------------------------------------------------
About compliance with *strong urge* of API towards burn_drive_scan_and_grab()
cdrskin was the initiator of the whitelist functionality within libburn.
Now it has problems to obviously comply with the new API best practice
presciptions literally. Therefore this explanation:
On start it restricts the library to a single drive if it already knows the
persistent address by option dev= . This is done with a combination of
burn_drive_add_whitelist() and burn_drive_scan(). Not compliant to the
literal strong urge but in fact exactly fulfilling the reason for that
urge in the API: any scanned drive might be opened exclusively after
burn_drive_scan(). It is kernel dependent wether this behavior is on, off
or switchable. The sysdamin will want it on - but only for one drive.
So with dev=... cdrskin complies to the spirit of the strong urge.
Without dev=... it has to leave out the whitelist in order to enable bus
scanning and implicit drive address 0. A tradition of 9 months shall not
be broken. So burns without dev= will stay possible - and are now harmless.
*
Only if the new API compliance is enabled by macro Cdrskin_new_api_tesT .
There is a flaw to be solved in libburn until new API compliance is in all
aspects as good as the old handcrafted attempt to be sysadmin friendly.
In many aspects it is already superior, note well.
As soon as the flaw http://libburn.pykix.org/ticket/10 is removed,
cdrskin will switch to its new way of API best practice compliance.
*
This is because Cdrskin_grab_drive() enforces a restart of the library
with the desired drive's persistent address. This restart then really uses
the strongly urged function burn_drive_scan_and_grab().
Thus, cdrskin complies with the new spirit of API by closing down libburn
as soon as the persistent drive address is known and the drive is to be
used with a long running operation. To my knowlege all long running
operations in cdrskin need a grabbed drive.
This spaghetti approach seems necessary to keep small the impact of new API
urge on cdrskin's stability. cdrskin suffers from having donated the body
parts which have been transplanted to libburn in order to create
burn_drive_scan_and_grab() . The desired sysadmin friendlyness was already
achieved by most cdrskin runs. The remaining problem situations should now
be defused by releasing any short time grabbed flocks of drives during the
restart of libburn.
------------------------------------------------------------------------------
Compilation within cdrskin-* : Compilation within cdrskin-* :
@ -1794,6 +1839,7 @@ struct CdrskiN {
}; };
int Cdrskin_destroy(struct CdrskiN **o, int flag); int Cdrskin_destroy(struct CdrskiN **o, int flag);
int Cdrskin_grab_drive(struct CdrskiN *skin, int flag);
int Cdrskin_release_drive(struct CdrskiN *skin, int flag); int Cdrskin_release_drive(struct CdrskiN *skin, int flag);
@ -2005,7 +2051,53 @@ int Cdrskin_adjust_speed(struct CdrskiN *skin, int flag)
} }
/** Obtain access to a libburn drive for writing or information retrieval /** Shutdown library and restart again on single drive which gets grabbed.
Does only work with a valid skin->driveno or with an already set
skin->preskin->device_adr .
@param flag Bitfield for control purposes:
bit0= skin->driveno points to a valid drive. The library
will get reopened with that drive listed as only one
and already grabbed.
@return 1 = success ,
0 = failure, drive is released, library initialized
-1 = failure, library is finished (and could not get initialized)
*/
int Cdrskin_reinit_lib_with_adr(struct CdrskiN *skin, int flag)
{
int ret;
if(skin->drive_is_grabbed)
Cdrskin_release_drive(skin,0);
if(flag&1)
burn_drive_get_adr(&(skin->drives[skin->driveno]),
skin->preskin->device_adr);
if(strlen(skin->preskin->device_adr)<=0) {
fprintf(stderr,
"cdrskin: FATAL : unable to determine persistent drive address\n");
ret= 0; goto ex;
}
burn_finish();
if(!burn_initialize()) {
fflush(stdout);
fprintf(stderr,"cdrskin : FATAL : Re-initialization of libburn failed\n");
{ret= -1; goto ex;}
}
ret= Cdrskin_grab_drive(skin,1); /* uses burn_drive_scan_and_grab() */
if(ret<=0)
{ret=0; goto ex;}
ret= 1;
ex:
return(ret);
}
/** Obtain access to a libburn drive for writing or information retrieval.
Extended behavior with Cdrskin_new_api_tesT:
If libburn is not restricted to a single persistent address then it
gets shutdown and restarted with the wanted drive only. Thus, after
this call, libburn is supposed to have open only the grabbed drive.
All other drives should be free for other use.
@param flag Bitfield for control purposes: @param flag Bitfield for control purposes:
bit0= bus is unscanned, device is known, bit0= bus is unscanned, device is known,
use burn_drive_scan_and_grab() use burn_drive_scan_and_grab()
@ -2037,15 +2129,27 @@ int Cdrskin_grab_drive(struct CdrskiN *skin, int flag)
#ifdef Cdrskin_new_api_tesT #ifdef Cdrskin_new_api_tesT
if(flag&1) { if(flag&1) {
fprintf(stderr, fprintf(stderr,
"cdrskin: experimental: Cdrskin_grab_drive() on Cdrskin_new_api_tesT\n"); "cdrskin: experimental: Cdrskin_grab_drive() from shutdown libburn\n");
ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr,1); ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr,1);
if(ret<=0) if(ret<=0) {
fprintf(stderr,"cdrskin: experimental: burn_drive_scan_and_grab ret=%d\n",
ret);
goto unable; goto unable;
}
skin->driveno= 0; skin->driveno= 0;
} else { } else {
fprintf(stderr,
"cdrskin: experimental: Cdrskin_grab_drive() on active libburn\n");
if(strlen(skin->preskin->device_adr)<=0) {
fprintf(stderr,
"cdrskin: experimental: Cdrskin_grab_drive() restarting libburn\n");
ret= Cdrskin_reinit_lib_with_adr(skin,1);
goto ex; /* this calls Cdrskin_grab() with persistent address or fails */
}
#else #else
@ -4018,12 +4122,12 @@ int main(int argc, char **argv)
if(skin->n_drives<=0) { if(skin->n_drives<=0) {
fprintf(stderr,"cdrskin: NOTE : no usable drive detected.\n"); fprintf(stderr,"cdrskin: NOTE : no usable drive detected.\n");
if(getuid()!=0) { if(getuid()!=0) {
fprintf(stderr,
"cdrskin: HINT : Busy drives are invisible. (Busy = open O_EXCL)\n");
fprintf(stderr, fprintf(stderr,
"cdrskin: HINT : Run this program as superuser with option --devices\n"); "cdrskin: HINT : Run this program as superuser with option --devices\n");
fprintf(stderr, fprintf(stderr,
"cdrskin: HINT : Allow rw-access to the dev='...' file of the burner.\n"); "cdrskin: HINT : Allow rw-access to the dev='...' file of the burner.\n");
fprintf(stderr,
"cdrskin: HINT : Busy drives are invisible. (Busy = open O_EXCL)\n");
} }
} }