2017年6月9日金曜日

ownCloudのマニュアルアップグレード

1ダウンロード
                以下からダウンロード

    2.ラズパイにコピー
              scp owncloud-10.x.x.zip username@192.168.x.xxx:
              最近はtar.bz2なので、
              scp owncloud-10.x.x.tar.bz2 username@192.168.x.xxx:

      3.ラズパイにSSHでログイン
              ssh username@192.168.x.xxx

      4.unzip
              ここからはsuで作業
              su
              cd ~username
              unzip owncloud-10.x.x.zip
              最近はtar.bz2なので、
              tar xf owncloud-10.x.x.tar.bz2

      5.Maintenance mode on
                 sudo -u www-data php occ maintenance:mode —on

      6.rename
                cd /var/www/owncloudのあるところ
                sudo mv ownclouod owncloud_old

      7.stop nginx
                 sudo /etc/init.d/nginx stop

      8.move owncloud
                   sudo mv ~username/owncloud ./owncloud

        9.copy config from old
                sudo cp owncloud_old/config/config.php owncloud/config/config.php

          10.start nginx
                  sudo /etc/init.d/nginx start

            11.Upgrade
                          sudo -u www-data php occ upgrade

              12.Maintenance mode off
                           sudo -u www-data php occ maintenance:mode —off


                2017年6月1日木曜日

                GetTickCountと49.7日問題にハマった

                1秒ごとに実行させたいといった場合

                【普通に思いつくコード】
                DWORD tkNext = ::GetTickCount()+1000;    // 1秒後の時間を計算しておく

                while (bRunning) {
                ::Sleep(1);    // Sleep(0)問題参照
                if(::GetTickCount() <= tkNext){
                continue;    // 1秒経って無ければcontinue
                }
                tkNext = ::GetTickCount()+1000;    // 1秒経ってるので、次の1秒を計算しておく
                // なんらかの処理をする
                }

                これね、何の問題もなさそうに見えたんですわ・・・

                しかし、下部のtkNext = ::GetTickCount()+1000のところで、
                ::GetTickCount()がDWORDの限界付近で、tkNextが0xffffffff付近になったとする
                ループの頭に戻って、GetTickCountした時にDWORDを一周りして、ゼロ以上になっていたら、
                (::Sleep(1)は10ミリ秒以上になるので)
                ::GetTickount() <= tkNextの所が、
                if(10 <= 0xffffffff)になってしまう
                すると、その後、ずっとcontinueしてしまうので、処理が行われなくなる。
                49.7日後に再びGetTickCountがゼロになり、処理まで進まない。
                (0xffffffff/1000/60/60/24 = 約49.7日)
                このプログラムはおよそ49.7日で動かなくなる可能性があるのだ。

                【修正版】
                DWORD tkPrev = GetTickCount();   // 以前実行した時刻を保存しておく
                while (bRunning) {
                ::Sleep(1);
                if(::GetTickCount() - tkPrev < 1000){
                continue;    // 前回実行時刻との差が1秒経って無ければcontinue
                }
                        tkPrev = ::GetTickCount();    // 1秒経ったので、現時刻を保存しとく
                // なんらかの処理をする
                }

                こうやって、::GetTickCount() - tkPrev で判断すれば、DWORDを一回りするタイミングでも問題が無い
                このコードは実はMSDNのGetTickCountでサンプルとして示されたコードとほぼ同一だ。
                このコードの肝は符号拡張の部分なので、怪しいなと思ったらDWORD変数を作ってループさせるプログラムでも作って検証してみると良い。