Esempio n. 1
0
File: log.cpp Progetto: nunb/mongo
    void start( const string& lp , bool append ) {
        uassert( 10268 ,  "LoggingManager already started" , ! _enabled );
        _append = append;

        bool exists = boost::filesystem::exists(lp);

        // test path
        FILE * test = fopen( lp.c_str() , _append ? "a" : "w" );
        if ( ! test ) {
            if (boost::filesystem::is_directory(lp)) {
                cout << "logpath [" << lp << "] should be a file name not a directory" << endl;
            }
            else {
                cout << "can't open [" << lp << "] for log file: " << errnoWithDescription() << endl;
            }
            dbexit( EXIT_BADOPTIONS );
            assert( 0 );
        }

        if (append && exists) {
            // two blank lines before and after
            const string msg = "\n\n***** SERVER RESTARTED *****\n\n\n";
            massert(14036, errnoWithPrefix("couldn't write to log file"),
                    fwrite(msg.data(), 1, msg.size(), test) == msg.size());
        }

        fclose( test );

        _path = lp;
        _enabled = 1;
        rotate();
    }
Esempio n. 2
0
    void FileAllocator::ensureLength(int fd , long size) {
#if !defined(_WIN32)
        if (useSparseFiles(fd)) {
            LOG(1) << "using ftruncate to create a sparse file" << endl;
            int ret = ftruncate(fd, size);
            uassert(16063, "ftruncate failed: " + errnoWithDescription(), ret == 0);
            return;
        }
#endif

#if defined(__linux__)
        int ret = posix_fallocate(fd,0,size);
        if ( ret == 0 )
            return;

        log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl;
#endif

        off_t filelen = lseek( fd, 0, SEEK_END );
        if ( filelen < size ) {
            if (filelen != 0) {
                stringstream ss;
                ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription();
                uassert( 10440 ,  ss.str(), filelen == 0 );
            }
            // Check for end of disk.

            uassert( 10441 ,  str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
                     size - 1 == lseek(fd, size - 1, SEEK_SET) );
            uassert( 10442 ,  str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
                     1 == write(fd, "", 1) );

            // File expansion is completed here. Do not do the zeroing out on OS-es where there
            // is no risk of triggering allocation-related bugs such as
            // http://support.microsoft.com/kb/2731284.
            //
            if (!ProcessInfo::isDataFileZeroingNeeded()) {
                return;
            }

            lseek(fd, 0, SEEK_SET);

            const long z = 256 * 1024;
            const boost::scoped_array<char> buf_holder (new char[z]);
            char* buf = buf_holder.get();
            memset(buf, 0, z);
            long left = size;
            while ( left > 0 ) {
                long towrite = left;
                if ( towrite > z )
                    towrite = z;

                int written = write( fd , buf , towrite );
                uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 );
                left -= written;
            }
        }
    }
Esempio n. 3
0
File: log.cpp Progetto: weliu/mongo
        void start( const string& lp , bool append ) {
            uassert( 10268 ,  "LoggingManager already started" , ! _enabled );
            _append = append;

            bool exists = boost::filesystem::exists(lp);
            bool isdir = boost::filesystem::is_directory(lp);
            bool isreg = boost::filesystem::is_regular(lp);

            if ( exists ) {
                if ( isdir ) {
                    cout << "logpath [" << lp << "] should be a filename, not a directory" << endl;
                    
                    dbexit( EXIT_BADOPTIONS );
                    assert( 0 );
                }

                if ( ! append ) {
                    // only attempt rename if log is regular file
                    if ( isreg ) {
                        stringstream ss;
                        ss << lp << "." << terseCurrentTime( false );
                        string s = ss.str();

                        if ( ! rename( lp.c_str() , s.c_str() ) ) {
                            cout << "log file [" << lp << "] exists; copied to temporary file [" << s << "]" << endl;
                        } else {
                            cout << "log file [" << lp << "] exists and couldn't make backup; run with --logappend or manually remove file (" << strerror(errno) << ")" << endl;
                            
                            dbexit( EXIT_BADOPTIONS );
                            assert( 0 );
                        }
                    }
                }
            }
            // test path
            FILE * test = fopen( lp.c_str() , _append ? "a" : "w" );
            if ( ! test ) {
                cout << "can't open [" << lp << "] for log file: " << errnoWithDescription() << endl;
                dbexit( EXIT_BADOPTIONS );
                assert( 0 );
            }

            if (append && exists){
                // two blank lines before and after
                const string msg = "\n\n***** SERVER RESTARTED *****\n\n\n";
                massert(14036, errnoWithPrefix("couldn't write to log file"),
                        fwrite(msg.data(), 1, msg.size(), test) == msg.size());
            }

            fclose( test );

            _path = lp;
            _enabled = 1;
            rotate();
        }
Esempio n. 4
0
    void FileAllocator::ensureLength(int fd , long size) {
#if !defined(_WIN32)
        if (useSparseFiles(fd)) {
            LOG(1) << "using ftruncate to create a sparse file" << endl;
            int ret = ftruncate(fd, size);
            uassert(16063, "ftruncate failed: " + errnoWithDescription(), ret == 0);
            return;
        }
#endif

#if defined(__linux__)
        int ret = posix_fallocate(fd,0,size);
        if ( ret == 0 )
            return;

        log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl;
#endif

        off_t filelen = lseek( fd, 0, SEEK_END );
        if ( filelen < size ) {
            if (filelen != 0) {
                stringstream ss;
                ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription();
                uassert( 10440 ,  ss.str(), filelen == 0 );
            }
            // Check for end of disk.

            uassert( 10441 ,  str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
                     size - 1 == lseek(fd, size - 1, SEEK_SET) );
            uassert( 10442 ,  str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
                     1 == write(fd, "", 1) );
            lseek(fd, 0, SEEK_SET);

            const long z = 256 * 1024;
            const boost::scoped_array<char> buf_holder (new char[z]);
            char* buf = buf_holder.get();
            memset(buf, 0, z);
            long left = size;
            while ( left > 0 ) {
                long towrite = left;
                if ( towrite > z )
                    towrite = z;

                int written = write( fd , buf , towrite );
                uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 );
                left -= written;
            }
        }
    }