From ff0be0eeae300b2595f1e271d9934072ca061116 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 7 Oct 2006 12:29:22 +0000 Subject: [PATCH] Got rid of assert() in drive.c by soft means --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/asserts.txt | 56 ++++++++++----- libburn/async.c | 30 +++++++-- libburn/drive.c | 131 +++++++++++++++++++++++++----------- libburn/drive.h | 6 +- libburn/init.c | 10 ++- libburn/libburn.h | 17 +++-- libburn/libdax_msgs.h | 7 ++ libburn/sg.c | 9 +++ 9 files changed, 198 insertions(+), 70 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index e090b04..73e4d7a 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2006.10.05.142628" +#define Cdrskin_timestamP "2006.10.07.121234" diff --git a/libburn/asserts.txt b/libburn/asserts.txt index 82f2463..314a5dd 100644 --- a/libburn/asserts.txt +++ b/libburn/asserts.txt @@ -87,16 +87,18 @@ ts A61006 --------------------------------------------------------------------- - 6) libburn/drive.c: assert(d->busy == BURN_DRIVE_IDLE); +++ 6) libburn/drive.c: assert(d->busy == BURN_DRIVE_IDLE); API burn_drive_release(): A drive is not idle on release. : Severe Application Error => Same as 4) +ts A61007 + ------------------------------------------------------------------------------ - 7) libburn/drive.c: assert(d->released); +++ 7) libburn/drive.c: assert(d->released); burn_wait_all() A drive is found grabbed. @@ -104,12 +106,16 @@ Called by burn_drive_scan_sync(), thread under API burn_drive_scan() Called by API burn_finish : Severe Application Error +=> rename and redefine burn_wait_all() : now burn_drives_are_clear() +=> change all use of burn_wait_all() => Move tests up to burn_drive_scan() -=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_SORRY +=> There: return -1; issue LIBDAX_MSGS_SEV_SORRY + +ts A61007 ------------------------------------------------------------------------------ - 8) libburn/drive.c: assert(!d->released); +++ 8) libburn/drive.c: assert(!d->released); API burn_disc_get_status() Attempt to read status of non-grabbed drive. @@ -117,20 +123,24 @@ Attempt to read status of non-grabbed drive. => extend enum burn_disc_status by BURN_DISC_UNGRABBED => return BURN_DISC_UNGRABBED, issue LIBDAX_MSGS_SEV_SORRY +ts A61007 + ------------------------------------------------------------------------------ - 9) libburn/drive.c: assert( /* (write_type >= BURN_WRITE_PACKET) && */ +++ 9) libburn/drive.c: assert( /* (write_type >= BURN_WRITE_PACKET) && */ burn_drive_get_block_types(): -Will not work on BURN_WRITE_RAW. +Will not work on BURN_WRITE below BURN_WRITE_RAW. Called by -nobody- ? : Severe Application Error => inactivate unused function +ts A61007 + ------------------------------------------------------------------------------ - 10) libburn/drive.c: assert(d->idata); +++ 10) libburn/drive.c: assert(d->idata); libburn/drive.c: assert(d->mdata); static drive_getcaps(): sg.c:enumerate_common() did not succeed in creating a proper struct burn_drive @@ -139,11 +149,14 @@ Called by burn_drive_scan_sync() : Severe System Error => This could possibly really stay an abort() because the reason is a plain failure of the system's memory management. -=> ? Detect this failure already in enumerate_common() ? +=> Detect this failure already in enumerate_common(), + issue LIBDAX_MSGS_SEV_FATAL, return + +ts A61007 ------------------------------------------------------------------------------ - 11) libburn/drive.c: assert(burn_running); +++ 11) libburn/drive.c: assert(burn_running); burn_drive_scan_sync(): The library was not initialized. @@ -151,20 +164,24 @@ Called as thread by API burn_drive_scan() : Severe Application Error => Move this test up to burn_drive_scan() -=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_SORRY +=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_FATAL + +ts A61007 ------------------------------------------------------------------------------ - 12) libburn/drive.c: assert(d->released == 1); +++ 12) libburn/drive.c: assert(d->released == 1); burn_drive_scan_sync(): Inactivated : (Severe Application Error) -=> Same as 7) +=> throw out inactivated code + +ts A61007 ------------------------------------------------------------------------------ - 13) libburn/drive.c: assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN); +++ 13) libburn/drive.c: assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN); burn_drive_raw_get_adr(): An enumerated device address is longer than the API's maximum length @@ -172,18 +189,21 @@ Called by API burn_drive_get_adr() Called by API burn_drive_obtain_scsi_adr() : Severe Libburn Error -=> return -1; in all three functions, enhance API @return docs +=> return -1; in all three functions, enhance burn_drive_get_adr @return docs => issue LIBDAX_MSGS_SEV_SORRY +ts A61007 + ------------------------------------------------------------------------------ - 14) libburn/drive.c: assert(drive_info->drive!=NULL); +++ 14) libburn/drive.c: assert(drive_info->drive!=NULL); API burn_drive_get_adr(): Drive info has no drive attached. -: Severe Libburn Error -=> return -1; enhance API @return docs -=> issue LIBDAX_MSGS_SEV_SORRY +: Severe Libburn Error (unlikely, will eventually SIGSEGV on NULL) +=> delete assert + +ts A61007 ------------------------------------------------------------------------------ diff --git a/libburn/async.c b/libburn/async.c index c0f41ba..71e57cb 100644 --- a/libburn/async.c +++ b/libburn/async.c @@ -6,6 +6,7 @@ #include "write.h" #include "options.h" #include "async.h" +#include "init.h" #include #include @@ -126,21 +127,41 @@ int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives) struct scan_opts o; int ret = 0; + /* ts A61006 : moved up from burn_drive_scan_sync , former assert */ + if (!burn_running) { + libdax_msgs_submit(libdax_messenger, -1, 0x00020109, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + "Library not running", 0, 0); + *drives = NULL; + *n_drives = 0; + return -1; + } + /* cant be anything working! */ /* ts A61006 */ /* a ssert(!(workers && workers->drive)); */ if (workers != NULL && workers->drive != NULL) { - libdax_msgs_submit(libdax_messenger, - workers->drive->global_index, 0x00020102, +drive_is_active:; + libdax_msgs_submit(libdax_messenger, -1, 0x00020102, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "A drive operation is still going on (want to scan)", 0, 0); + *drives = NULL; + *n_drives = 0; return -1; } if (!workers) { /* start it */ + + /* ts A61007 : test moved up from burn_drive_scan_sync() + was burn_wait_all() */ + if (!burn_drives_are_clear()) + goto drive_is_active; + *drives = NULL; + *n_drives = 0; + o.drives = drives; o.n_drives = n_drives; o.done = 0; @@ -152,12 +173,13 @@ int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives) /* ts A61006 */ /* a ssert(workers == NULL); */ - if (workers != NULL) + if (workers != NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020101, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "After scan a drive operation is still going on", 0, 0); - return -1; + return -1; + } } else { /* still going */ diff --git a/libburn/drive.c b/libburn/drive.c index e49a679..dfec94e 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -5,7 +5,10 @@ #include #include #include -#include + +/* ts A61007 */ +/* #include */ + #include #include #include @@ -261,11 +264,26 @@ int burn_drive_unregister(struct burn_drive *d) void burn_drive_release(struct burn_drive *d, int le) { - if (d->released) - burn_print(1, "second release on drive!\n"); + if (d->released) { + /* ts A61007 */ + /* burn_print(1, "second release on drive!\n"); */ + libdax_msgs_submit(libdax_messenger, + d->global_index, 0x00020105, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Drive is already released", 0, 0); + return; + } + /* ts A61007 */ /* ts A60906: one should not assume BURN_DRIVE_IDLE == 0 */ - assert(d->busy == BURN_DRIVE_IDLE); + /* a ssert(d->busy == BURN_DRIVE_IDLE); */ + if (d->busy != BURN_DRIVE_IDLE) { + libdax_msgs_submit(libdax_messenger, + d->global_index, 0x00020106, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Drive is busy on attempt to close", 0, 0); + return; + } d->unlock(d); if (le) @@ -285,6 +303,26 @@ void burn_drive_release(struct burn_drive *d, int le) } } + + +/* ts A61007 : former void burn_wait_all() */ +int burn_drives_are_clear(void) +{ + int i; + + for (i = burn_drive_count() - 1; i >= 0; --i) { + /* ts A60904 : ticket 62, contribution by elmom */ + if (drive_array[i].global_index == -1) + continue; + if (drive_array[i].released) + continue; + return 0; + } + return 1; +} + + +#if 0 void burn_wait_all(void) { unsigned int i; @@ -300,12 +338,14 @@ void burn_wait_all(void) if (d->global_index==-1) continue; - assert(d->released); + a ssert(d->released); } if (!finished) sleep(1); } } +#endif + void burn_disc_erase_sync(struct burn_drive *d, int fast) { @@ -346,7 +386,17 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast) enum burn_disc_status burn_disc_get_status(struct burn_drive *d) { - assert(!d->released); + /* ts A61007 */ + /* a ssert(!d->released); */ + if (d->released) { + libdax_msgs_submit(libdax_messenger, + d->global_index, 0x00020108, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Drive is not grabbed on disc status inquiry", + 0, 0); + return BURN_DISC_UNGRABBED; + } + return d->status; } @@ -371,12 +421,13 @@ void burn_drive_cancel(struct burn_drive *d) pthread_mutex_unlock(&d->access_lock); } -#ifdef NIX +/* ts A61007 : defunct because unused */ +#if 0 int burn_drive_get_block_types(struct burn_drive *d, enum burn_write_types write_type) { burn_print(12, "write type: %d\n", write_type); - assert( /* (write_type >= BURN_WRITE_PACKET) && */ + a ssert( /* (write_type >= BURN_WRITE_PACKET) && */ (write_type <= BURN_WRITE_RAW)); return d->block_types[write_type]; } @@ -407,8 +458,12 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out) { struct scsi_inquiry_data *id; - assert(d->idata); - assert(d->mdata); + /* ts A61007 : now prevented in enumerate_common() */ +#if 0 + a ssert(d->idata); + a ssert(d->mdata); +#endif + if (!d->idata->valid || !d->mdata->valid) return 0; @@ -454,27 +509,21 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[], static int scanning = 0, scanned = 0, found = 0; static unsigned num_scanned = 0, count = 0; unsigned int i; -#ifdef Libburn_ticket_62_enable_redundant_asserT - struct burn_drive *d; -#endif - assert(burn_running); + /* ts A61007 : moved up to burn_drive_scan() */ + /* a ssert(burn_running); */ if (!scanning) { scanning = 1; + + /* ts A61007 : test moved up to burn_drive_scan() + burn_wait_all() is obsoleted */ +#if 0 /* make sure the drives aren't in use */ burn_wait_all(); /* make sure the queue cleans up before checking for the released state */ - - /* ts A60904 : ticket 62, contribution by elmom */ - /* this is redundant with what is done in burn_wait_all() */ -#ifdef Libburn_ticket_62_enable_redundant_asserT - d = drive_array; - count = burn_drive_count(); - for (i = 0; i < count; ++i, ++d) - assert(d->released == 1); -#endif /* Libburn_ticket_62_enable_redundant_asserT */ +#endif /* 0 */ /* refresh the lib's drives */ sg_enumerate(); @@ -520,7 +569,7 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]) burn_drive_info is not the manager of burn_drive but only its spokesperson. To my knowlege drive_infos from burn_drive_scan() are not memorized globally. */ - if(drive_infos != NULL) /* and this NULL test is deadly necessary */ + if(drive_infos != NULL) free((void *) drive_infos); burn_drive_free_all(); @@ -650,27 +699,20 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr, fprintf(stderr,"libburn: experimental: burn_drive_scan_and_grab(%s)\n", adr); */ - while (!burn_drive_scan(drive_infos, &n_drives)) + while (1) { + ret = burn_drive_scan(drive_infos, &n_drives); + if (ret < 0) + return -1; + if (ret > 0) + break; usleep(1002); + } if (n_drives <= 0) return 0; /* fprintf(stderr, "libburn: experimental: n_drives == %d\n",n_drives); */ -/* ts A60908 : seems we get rid of this :) */ -#ifdef Libburn_grab_release_and_grab_agaiN - if (load) { - /* RIP-14.5 + LITE-ON 48125S produce a false status - if tray was unloaded */ - /* Therefore the first grab is just for loading */ - ret= burn_drive_grab(drive_infos[0]->drive, 1); - if (ret != 1) - return -1; - burn_drive_release(drive_infos[0]->drive,0); - } -#endif /* Libburn_grab_release_and_grab_agaiN */ - ret = burn_drive_grab(drive_infos[0]->drive, load); if (ret != 1) return -1; @@ -704,7 +746,13 @@ int burn_drive_adr_debug_msg(char *fmt, char *arg) /** Inquire the persistent address of the given drive. */ int burn_drive_raw_get_adr(struct burn_drive *d, char adr[]) { - assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN); + if (strlen(d->devname) >= BURN_DRIVE_ADR_LEN) { + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00020110, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + "Persistent drive address too long", 0, 0); + return -1; + } strcpy(adr,d->devname); return 1; } @@ -715,7 +763,6 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]) { int ret; - assert(drive_info->drive!=NULL); ret = burn_drive_raw_get_adr(drive_info->drive, adr); return ret; } @@ -818,7 +865,9 @@ int burn_drive_obtain_scsi_adr(char *path, if (drive_array[i].global_index < 0) continue; ret = burn_drive_raw_get_adr(&(drive_array[i]),adr); - if (ret <= 0) + if (ret < 0) + return -1; + if (ret == 0) continue; if (strcmp(adr, path) == 0) { *host_no = drive_array[i].host; diff --git a/libburn/drive.h b/libburn/drive.h index a0dd4cd..96d77e5 100644 --- a/libburn/drive.h +++ b/libburn/drive.h @@ -38,7 +38,11 @@ struct burn_drive *burn_drive_register(struct burn_drive *); int burn_drive_unregister(struct burn_drive *d); unsigned int burn_drive_count(void); -void burn_wait_all(void); + +/* ts A61007 */ +/* void burn_wait_all(void); */ +int burn_drives_are_clear(void); + int burn_sector_length_write(struct burn_drive *d); int burn_track_control(struct burn_drive *d, int); void burn_write_empty_sector(int fd); diff --git a/libburn/init.c b/libburn/init.c index 63e071e..c721054 100644 --- a/libburn/init.c +++ b/libburn/init.c @@ -81,7 +81,15 @@ void burn_finish(void) { assert(burn_running); - burn_wait_all(); + /* ts A61007 */ + /* burn_wait_all(); */ + if (!burn_drives_are_clear()) { + libdax_msgs_submit(libdax_messenger, -1, 0x00020107, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Drive is busy on attempt to shut down library", + 0, 0); + return; + } /* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */ burn_drive_free_all(); diff --git a/libburn/libburn.h b/libburn/libburn.h index 2072804..c2c92a4 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -172,7 +172,11 @@ enum burn_disc_status /** There is an incomplete disc in the drive */ BURN_DISC_APPENDABLE, /** There is a disc with data on it in the drive */ - BURN_DISC_FULL + BURN_DISC_FULL, + + /* ts A61007 */ + /** The drive was not grabbed when the status was inquired */ + BURN_DISC_UNGRABBED }; @@ -419,7 +423,8 @@ int burn_abort(int patience, int burn_abort_pacifier(void *handle, int patience, int elapsed); -/** Set the verbosity level of the library. The default value is 0, which means +/** ts A61006 : This is for development only. Not suitable for applications. + Set the verbosity level of the library. The default value is 0, which means that nothing is output on stderr. The more you increase this, the more debug output should be displayed on stderr for you. @param level The verbosity level desired. 0 for nothing, higher positive @@ -510,7 +515,9 @@ void burn_drive_clear_whitelist(void); before burn_finish(), and also before calling this function burn_drive_scan() again. @param n_drives Returns the number of drive items in drive_infos. - @return Zero while scanning is not complete; non-zero when it is finished. + @return 0 while scanning is not complete + >0 when it is finished sucessfully, + <0 when finished but failed. */ int burn_drive_scan(struct burn_drive_info *drive_infos[], unsigned int *n_drives); @@ -545,6 +552,7 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]); @param drive_info The drive to inquire. Usually some &(drive_infos[driveno]) @param adr An application provided array of at least BURN_DRIVE_ADR_LEN characters size. The persistent address gets copied to it. + @return >0 success , <=0 error (due to libburn internal problem) */ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]); @@ -615,6 +623,7 @@ void burn_drive_release(struct burn_drive *drive, int eject); for details. @param drive The drive to query for a disc. @return The status of the drive, or what kind of disc is in it. + Note: BURN_DISC_UNGRABBED indicates wrong API usage */ enum burn_disc_status burn_disc_get_status(struct burn_drive *drive); @@ -643,7 +652,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive); */ void burn_write_opts_free(struct burn_write_opts *opts); -/** Creates a write_opts struct for reading from the specified drive +/** Creates a read_opts struct for reading from the specified drive must be freed with burn_write_opts_free @param drive The drive to read from @return The read_opts diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index fc54d66..3a7d950 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -309,6 +309,13 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020102 (SORRY,HIGH) = A drive operation is still going on 0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on 0x00020104 (SORRY,HIGH) = NULL pointer caught + 0x00020105 (SORRY,HIGH) = Drive is already released + 0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close + 0x00020107 (SORRY,HIGH) = Drive is busy on attempt to shut down library + 0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry + 0x00020108 (FATAL,HIGH) = Could not allocate new drive object + 0x00020109 (FATAL,HIGH) = Library not running + 0x00020110 (FATAL,HIGH) = Persistent drive address too long ------------------------------------------------------------------------------ diff --git a/libburn/sg.c b/libburn/sg.c index bd7b847..f4260c4 100644 --- a/libburn/sg.c +++ b/libburn/sg.c @@ -450,6 +450,15 @@ static void enumerate_common(char *fname, int bus_no, int host_no, out.idata->valid = 0; out.mdata = malloc(sizeof(struct scsi_mode_data)); out.mdata->valid = 0; + + /* ts A61007 : obsolete assert() in drive_getcaps() */ + if(out.idata == NULL || out.mdata == NULL) { + libdax_msgs_submit(libdax_messenger, -1, 0x00020108, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + "Could not allocate new drive object", 0, 0); + return; + } + memset(&out.params, 0, sizeof(struct params)); t = burn_drive_register(&out);