예제 #1
0
파일: grpmain.c 프로젝트: yeonsh/Amoeba
errstat
sp_commit()
{
    struct sp_table *st;
    struct sp_save  *firstmod;
    objnum  obj;
    errstat err;
    
    /* When we get an error writing to the (probably local) bulletsvr,
     * we can do nothing but panic().  We cannot abort the transaction
     * because the other members will (presumably?) not have this problem
     * and hence have accepted the modification.
     */

    /* First see if we have multiple modifications as a result of the last
     * command. (This may happen as a result of sp_install()).
     * If so, we must use the intentions module rather than the modlist module
     * in order to guarantee atomicity.
     */
    st = sp_first_update();
    firstmod = (st != NULL) ? st->st_dir->sd_mods : NULL;

    if ((firstmod != NULL && firstmod->ss_next == NULL) /* just 1 mod */
	&& (st->st_dir->sd_update == NULL)		/* just 1 dir */)
    {
	obj = st - _sp_table;

	assert(sp_in_use(st));

	if (st->st_flags & SF_DESTROYING) {
	    MON_EVENT("destroying dir");
	    (void) remove_dir(obj);
	} else {
	    /* Note: we don't increase the current seqno of the directory
	     * itself, but use as the new seqnr the (already incremented)
	     * *global* sequence number.
	     * This avoids the possibility of having different incarnations
	     * of the same directory at the same time.
	     */
	    get_global_seqno(&st->st_dir->sd_seq_no);

	    err = ml_store(obj);
	    if (err != STD_OK && err != STD_NOSPACE) {
		/* Command not handled by modlist module, or no space in the
		 * modlist itself, or not enough memory.
		 */
		if (!ml_in_use()) {
		    /* Try to modify it, when possible and efficient.
		     * Otherwise write it out as a whole.
		     */
		    err = write_new_dir(obj, 1);
		} else {
		    /* Write it as a whole and remove it from the mod list */
		    err = ml_write_dir(obj);
		}
	    }

	    switch (err) {
	    case STD_OK:
		sp_free_mods(st);
		break;

	    case STD_NOSPACE:
		/* The directory would become to big.  This error should be
		 * consistent to all members, because they have the same
		 * data and use the same buffer sizes.
		 */
		scream("dir %ld would become too big", (long) obj); 
		sp_abort();	/* undoes the modification */
		return err;

	    default:
		/* must panic; see above */
		panic("sp_commit: cannot write dir %ld (%s)",
		      (long) obj, err_why(err));
	    }
	}
    } else {
	/* There are multiple updates or no updates at all */
	capability curcaps[NBULLETS];
	capability newcaps[NBULLETS];
	capability filesvrs[NBULLETS];
	struct sp_table *next_st;
	int nintents, avail;

	/* First make sure we have room for all of the intentions. */
	avail = intent_avail();
	nintents = 0;
	for (st = sp_first_update(); st != NULL; st = sp_next_update()) {
	    nintents++;
	}
	if (nintents > avail) {
	    scream("too many intentions: %d (max %d)", nintents, avail);
	    MON_EVENT("too many intentions");
	    sp_abort();
	    return STD_NOSPACE;
	}

	fsvr_get_svrs(filesvrs, NBULLETS);

	for (st = sp_first_update(); st != NULL; st = next_st ) {
	    next_st = sp_next_update();
	    obj = st - _sp_table;

	    /* Add an updated version of this dir to the intentions list.
	     * All dirs for which we have modifications should be in memory:
	     */
	    assert(sp_in_use(st));
	    assert(in_cache(obj));
    
	    /* Note: all directories modified in as a result of the current
	     * modification get the same seqno!
	     */
	    get_global_seqno(&st->st_dir->sd_seq_no);

	    if (!ml_in_use()) {
		/* Try to modify it, when possible and efficient.
		 * Otherwise write it out as a whole.
		 */
		get_dir_caps(obj, curcaps);
		err = dirf_modify(obj, NBULLETS, curcaps, newcaps, filesvrs);
	    } else {
		err = dirf_write(obj, NBULLETS, newcaps, filesvrs);
	    }

	    switch (err) {
	    case STD_OK:
		/* Put the new cap(s) in the intentions list.  Don't install
		 * them in the supertable yet: that'll be done after we have
		 * written the intention.  It'll also give us the opportunity
		 * to destroy the old versions afterwards.
		 */
		intent_add(obj, newcaps);
		MON_EVENT("added intention");
		break;

	    case STD_NOSPACE:
		/* The directory would become to big.  This error should be
		 * consistent to all members, because they have the same
		 * data and use the same buffer sizes.
		 * Remove the intentions and let the transaction fail.
		 */
		intent_undo();
		scream("dir %ld would become too big", (long) obj); 
		sp_abort();	/* undoes the modifications */
		return err;

	    default:	    /* must panic; see above */
		panic("sp_commit: cannot write dir %ld (%s)",
		      (long) obj, err_why(err));
	    }
	}

	if (nintents > 0) {
	    /* Write the intentions created to disk */
	    super_store_intents();

	    /* Install the modified directories in the super table and remove
	     * the intention again.  If we happen to crash between storing the
	     * intention and executing it, we'll complete it the next time
	     * during recovery.
	     */
	    intent_make_permanent();
	    MON_EVENT("executed intention");
	}
    }

    sp_clear_updates();
    sp_end();
    return STD_OK;
}
예제 #2
0
파일: SPIT152.C 프로젝트: tig/Tigger
/*--------------------------------------------------------------------------*/
main (int argc, char *argv[])
{    char   option;                    /* command line option */
     char   *infile,
            *outfile,
            *cur;

     FILE *fopen (), *in_f, *out_f;
     extern int getopt (int argc, char *argv[], char *optionS);
     extern int optind,                /* the argv index of the next argument */
                opterr;                /* set this to zero so that getopt dont print its own error */
     extern char *optarg;              /* points to the option argument */
     struct stat f_info;               /* structure for stat */
     long secs_now;

     NumLines = DEFLINES;
     PageLen = DEFPAGE;
     NumCols = DEFCOL;
     NumIndent = DEFINDENT;
     outfile = NULL;
     opterr = 0;
     out_f = stdout;

     textcolor (YELLOW);
/*     clrscr ();*/
     cprintf (" SPIT V%s", VERSION);
     cprintf (" -file printer and formatter- ");
     cprintf ("(c)1987,88 KindelCo Software Systems\n\n");

     if (argc == 1)                    /* if there is nothing on the command line then print docs */
         sp_abort (NOERR);

     textcolor (LIGHTMAGENTA);
     while ((option = getopt (argc, argv, OPTSTRING)) != EOF)
         switch (toupper (option))
         {  case LINE_OPT    : NumLines = strtol (optarg, NULL, 0); /* strtol converts a string to a long int. */
                               cprintf ("    spit: Option not implemented yet: /%c.\n", option);
                               sp_abort (CMNDERR);
                               break;
            case PAGE_OPT    : PageLen = strtol (optarg, NULL, 0);
                               cprintf ("    spit: Option not implemented yet: /%c.\n", option);
                               sp_abort (CMNDERR);
                               PageLen = strtol (optarg, NULL, 0);
                               break;
            case WIDE_OPT    : if (NumIndent == DEFINDENT)
                                  NumIndent = 8;
                               NumCols = 132;
                               wideflg = TRUE;
                               break;
            case OUT_OPT     : outfile = malloc (strlen (optarg));
                               outfile = optarg;
                               break;
            case INDENT_OPT  : NumIndent = strtol (optarg, NULL, 0);
                               break;
            case UNKNOWN_OPT : cprintf ("    spit: unknown command line option.\n");
                               sp_abort (CMNDERR);
                               break;
            case FF_OPT      : formflg = TRUE;
                               break;
            case SINGLE_OPT  : singleflg = TRUE;
                               break;
            default          : cprintf ("    spit: Option not implemented yet: /%c.\n", option);
                               sp_abort (CMNDERR);
                               break;
         }


     if (NumLines >= (PageLen - 8))
     {  cprintf ("    spit: The number of lines must not exceed the page length - 8.\n");
        sp_abort (OPTERR);
     }

     while (optind < argc)
     {    infile = (char*) malloc (strlen (argv[optind])+2);
          strcpy (infile, argv [optind++]);
          if ((in_f = fopen (infile, READ)) == NULL)
          {    cprintf ("     spit: can't open input file ");
               textcolor (WHITE);
               cprintf ("%s\n", infile);
               textcolor (LIGHTMAGENTA);
               sp_abort (INFILEERR);
          }
          if (outfile == NULL)
          {   outfile = malloc (4);
              strcpy (outfile, DEFOUT);
          }

          if ((out_f = fopen (outfile, WRITE)) == NULL)
          {   cprintf ("     spit: can't open output file ");
              textcolor (WHITE);
              cprintf ("%s\n", outfile);
              textcolor (LIGHTMAGENTA);
              sp_abort (OUTFILEERR);
          }

          cprintf ("Printing ");
          textcolor (WHITE);
          cprintf ("%s ", infile);
          textcolor (LIGHTMAGENTA);
          cprintf ("...");

          if (strlen (infile) > 19)
          {   strcpy (header, infile);
              cur = header;
              while (strlen (cur) > 16)
                 *(cur++) = '.';
              cur -= 3;
              strcpy (header, cur);
              strcat (header, " ");
          }
          else
          {   strcpy (header, infile);
              while (strlen (header) < 20)
                 strcat (header, " ");
          }

          strcat (header, "-  Revised ");
          stat (infile, &f_info);               /* get file date */
          strcat (header, ctime (&f_info.st_mtime));
          *strchr (header, '\n') = NULL;
          strcat (header, "  -");
          while (strlen (header) < 69)
             strcat (header, " ");
          strcat (header, "Page ");

          strcpy (footer, "                   -  Printed on \0");
          time (&secs_now);                    /* get time in seconds */
          strcat (footer, ctime (&secs_now));  /* make it into a string */
          *(strchr (footer, '\n')) = NULL;
          strcat (footer, "  -");
          sp_io (in_f, out_f);
          if (fclose (in_f))
            cprintf ("Error closing input file.");
          if (fclose (out_f))
            cprintf ("Error closing output file.");
          cprintf ("\n");
          free (infile);
     }
     cprintf ("\n");
     return;
}
예제 #3
0
파일: SPIT142.C 프로젝트: tig/Tigger
/*--------------------------------------------------------------------------*/
main (int argc, char *argv[])
{    char   option;                    /* command line option */
     char   *infile,
            *outfile;
     FILE *fopen (), *in_f, *out_f;
     extern int getopt (int argc, char *argv[], char *optionS);
     extern int optind,                /* the argv index of the next argument */
                opterr;                /* set this to zero so that getopt dont print its own error */
     extern char *optarg;              /* points to the option argument */
     struct stat f_info;               /* structure for stat */
     long secs_now;

     directvideo = FALSE;              /* we don't want direct video! */

     NumLines = DEFLINES;
     PageLen = DEFPAGE;
     NumCols = DEFCOL;
     NumIndent = DEFINDENT;
     outfile = NULL;
     opterr = 0;
     out_f = stdout;

     textcolor (YELLOW);
     cprintf (" SPIT V%s", VERSION);
     cprintf (" -file printer and formatter- ");
     cprintf ("(c)1987,88 KindelCo Software Systems\n\n");

     if (argc == 1)                    /* if there is nothing on the command line then print docs */
         sp_abort ();

     textcolor (LIGHTMAGENTA);
     while ((option = getopt (argc, argv, OPTSTRING)) != EOF)
         switch (option)
         {  case LINE_OPT    : NumLines = strtol (optarg, NULL, 0); /* strtol converts a string to a long int. */
                               break;
            case WIDE_OPT    : NumCols = 132;
                               NumIndent = 8;
                               wideflg++;
                               break;
            case OUT_OPT     : outfile = malloc (strlen (optarg));
                               outfile = optarg;
                               break;
            case INDENT_OPT  : NumIndent = strtol (optarg, NULL, 0);
                               break;
            case UNKNOWN_OPT : cprintf ("    spit: bad command line option...\n", option);
                               sp_abort ();
                               break;
            case FF_OPT      : formflg++;
                               break;
            default          : cprintf ("    spit: Option not implemented yet.\n");
                               sp_abort ();
                               break;
         }

     infile = malloc (256);

     while (optind < argc)                /* get each input file */
     {    strcpy (infile, argv [optind]);
          if ((in_f = fopen (infile, READ)) == NULL)
          {    cprintf ("     spit: can't open input file ");
               textcolor (WHITE);
               cprintf ("%s\n", infile);
               textcolor (LIGHTMAGENTA);
               sp_abort ();
          }
          optind--;
          if (outfile == NULL)
          {   outfile = malloc (4);
              strcpy (outfile, DEFOUT);
          }

          if ((out_f = fopen (outfile, WRITE)) == NULL)
          {   cprintf ("     spit: can't open output file ");
              textcolor (WHITE);
              cprintf ("%s\n", outfile);
              textcolor (LIGHTMAGENTA);
              sp_abort ();
          }

          strcpy (header, infile);
          while (strlen (header) < 20)
             strcat (header, " ");
          strcat (header, "-  Revised ");
          stat (infile, &f_info);               /* get file date */
          strcat (header, ctime (&f_info.st_mtime));
          *strchr (header, '\n') = NULL;
          strcat (header, "  -");
          while (strlen (header) < 69)
             strcat (header, " ");
          strcat (header, "Page ");

          while (strlen (footer) < 20)
             strcat (footer, " ");
          strcat (footer, "-  Printed on ");
          time (&secs_now);                    /* get time in seconds */
          strcat (footer, ctime (&secs_now));  /* make it into a string */
          *(strchr (footer, '\n')) = NULL;
          strcat (footer, "  -");
          sp_io (in_f, out_f);
     }
     cprintf ("\n");
     return;
}