Is it necessary to explicitly flush the HDD on-disk write caches?












1















Abstract



Sometimes, the Linux kernel is not aware of on-drive write caches of external USB storage devices. Is it necessary in such situations to explicitly flush those caches prior detaching these devices?



Example



I use a WD Elements external USB HDD of which hdparm -I says



...
Commands/features:
Enabled Supported:
...
* Write cache
...


and hdparm -W:



...
write-caching = 1 (on)


On the other hand, when I plug in the drive, I get the following kernel messages for it:



... No Caching mode page found
... Assuming drive cache: write through


According to this answer by Kyle Jones, these kernel messages indicate that the kernel assumes that its write operations will go directly to the platter.



The section "write_cache (RW)" of the file Documentation/block/queue-sysfs.txt in the Linux Kernel Documentation describes an implication of the kernel assuming a write through cache mode (thanks to Wayne Conrad):




... "write through", ... will also eliminate cache flushes issued by
the kernel.




Questions



Up to now, my standard method to detach external USB storage devices from a Linux system was to unmount all mounted partitions on it, to wait until the drive's LED stops flashing, to physically unplug the USB connector, and if this does not power down the device (some have a separate power supply), to explicitly power it down.



Is this method safe, or does it imply the risk of loosing unflushed data in the on-drive write cache, in particular if the kernel is unaware of that cache?



In the latter case, it seems to be advisable to explicitly flush the on-drive write cache after the unmount by sending an SCSI sync command. This can be done for example using sg_sync which comes with the sg3-utils:



sg_sync <device>


Would this solve the problem? Or should this be supplemented by an SCSI stop command to the device?



The latter could be issued with (again sg3-utils):



sg_start 0 -r <device>


Are sg_sync and sg_start the right tools for this purpose or is it better to use one of the tools and methods that I mention below in section "Related methods" or to do something else to handle the problem?



To point out the relevance of this question, see this comment by ack.



Please note: I am not looking for a method to primarily spin down or power off a HDD by software—unplugging the drive and using power switches have proven to be rather reliable in this respect. Instead, I am looking for a method that guarantees that all written data have made it to a non-volatile storage prior the drive is shut down, including data that was cached on-drive.



Related methods



In the following, I give some comments on methods that I found to be related to flushing on-drive caches or, more general, to "safe removal" of removable storage devices. There, one aspect is the availability of the involved tools on existing Linux systems. This matters because it is not always possible to simply install missing software.



Desktop environment: Some desktop environments offer widgets to "safely remove" external USB storage devices. See for example these questions:




  • "Eject / safely remove vs umount" by LGenzelis,


  • "How works the "eject usb driver" from Gnome?" by k.Cyborg.



and related posts.



Depending on the implementation, these widgets seem to power down the devices, but I did not find any reference that clarifies whether they cause the devices to flush their caches beforehand, especially in cases in which the kernel is not aware of external on-drive caches.



In addition, many Linux systems (for example pure servers) do not have any desktop environment installed. So this method is not always available.



udisks: According to this answer by jimmij, udisks by Freedesktop.org can be used from the command line to "safely remove" an external USB storage device:



udisks --unmount /dev/sda1
udisks --detach /dev/sda


This excellent answer by Totor describes what the udisks --detach command does:





  • sends SCSI sync-cache command,

  • sends SCSI stop command,

  • unbinds the usb-storage kernel driver,

  • suspends the USB device (power),

  • logically disables/removes it from its USB port.




So it explicitly takes care of the on-drive caches. However, udisks is only available on about one half of the Linux systems I have to deal with.



udisksctl: Recent versions of udisks provide for the program udisksctl, that can be used for a substitute of the udisks commands shown above. This is again according to jimmij's answer:



udisksctl unmount -b <partition>
udisksctl power-off -b <device>


The same answer also cites the description of the power-off command in the udisksctl(1) man page:




power-off



Arranges for the drive to be safely removed and powered off. On the OS
side this includes ensuring that no process is using the drive, then
requesting that in-flight buffers and caches are committed to stable
storage.




Unfortunately this does not specify whether the "in-flight buffers and caches" includes external on-drive caches that the kernel is not aware of. But it is likely that udisksctl follows its predecessor udisks in this respect.



Unfortunately, udisksctl definitely does follow its predecessor with respect to its rather low availability on existing systems (compared to the availability of umount, for example).



eject: According to its man page, the command line tool eject can be used to eject removable media under software control. Affected partitions will be unmounted beforehand as needed.



Albeit this tool shows up in several discussions on "safe removal" of removable media, see for example this question by LGenzelis and this question by k.Cyborg, nothing indicates that it does more than an unmount in this respect.



In addition, I suspect that this tool focuses more on media and media trays than on devices. This might be the reason why it simply dies with the error message



eject: unable to eject


when it is applied on the WD Elements USB drive that I mentioned as the introductory example above. However, it succeeds on some USB memory sticks.



Nevertheless, as a part of the linux-utils, this tool is highly available.



sg3-utils: The programs sg_sync and sg_start were already discussed above.



This comment by quirks to an Ubuntu bug report indicates that udisks internally uses the sg3-utils to send its SCSI sync and stop commands to the device.



It seems to me that the sg3-utils have a wider availability than udisks. But this is only a vague and personal impression.



sdparm: This web page by Yan Li discusses a procedure to "Safely remove an USB hard drive in Linux". For that purpose, it recommends a script that in principle uses the following sdparm commands to flush on-drive caches and to stop (spin down?) the USB HDD:



sdparm --command=sync <device>
sdparm --command=stop <device>


These seem to be comparable to the sg_sync and sg_start commands discussed above, and might be used as a substitute for the latter.



hdparm: Being basically a tool to manage ATA drives, hdparm is in some sense a foreign object when it comes to USB drives, because the latter are primarily addressed as SCSI devices in Linux. In cases like our WD Elements example, there is an ATA HDD sitting behind an SCSI to ATA translation layer (SAT layer). See this answer by Mikko Rantalainen for more details. Depending on the SAT's implementation, hdparm can be used with limited functionality to manipulate these drives.



If supported, one can use the commands



hdparm -F <device>
hdparm -Y <device>


to flush the on-drive caches and to stop the drives. If this is not possible, one might think of using



hdparm -W0 <device>


as a workaround to flush the caches. But beware: This command is actually intended to switch the on-drive write caching off. Therefore one should make sure that it actually flushes rather than simply drops the cache contents that was accumulated up to now.



For the WD Elements drive, none of these commands work: Instead they report bad/missing sense data.



sysfs: Scattered over the web, there are recipes to unbind an external USB drive from its driver, to unregister the drive from the system, or to power it down by manipulating device attributes that the Linux kernel exposes in its sysfs.



Here is an example from this post by bash in the Debian forum:



echo "auto" > "/sys/bus/usb/devices/usb1/1-5/power/level"
echo "1-5:1.0" > /sys/bus/usb/devices/1-5:1.0/driver/unbind


and



echo "1" > "/sys/bus/usb/devices/usb1/1-5/remove"


Or from this answer by Tony George:



echo 'offline' > /sys/block/sdb/device/state
echo '1' > /sys/block/sdb/device/delete


I have too little knowledge about the concepts that the kernel developers had in mind regarding the usage of these attributes to be able to judge these code snippets. But I have some doubt that they are helpful to flush on-drive write caches that the kernel is not aware of.



In addition, it seems that at least some of these recipes are outdated. In this respect, see the first paragraph of the "Sysfs Rules" in the kernel documentation as of 2019-01-25:




The kernel-exported sysfs exports internal kernel implementation
details and depends on internal kernel structures and layout. It is
agreed upon by the kernel developers that the Linux kernel does not
provide a stable internal API. Therefore, there are aspects of the
sysfs interface that may not be stable across kernel releases.




Umount and wait: This is the method that I referred to in my question above: It comprises an unmount and a subsequent waiting until the (presumably) write activities on the drive have finally ceased. The next and final step is to hope that the on-drive write caches were flushed in the course of that.



It is the main point of this question to clarify whether this is a safe method (for the data).



In any case, this method has the big advantage that it is easy, it is available on any Linux system I know, and the syntax of the umount command did not change over decades.



Further reading



Some general discussions about "ejecting" and "safe removal" of USB or other external storage devices can be found in the context of these questions:




  • "Safest way to remove USB drive on Linux [duplicate]" by Pkkm,


  • "Eject USB drives / eject command" by Joe Barr,


  • "When is it safe to disconnect my external HDD?" by jcora.



In addition, Luis Alvarado describes in this answer the differences between the options "Unmount", "Eject", and "Safely Remove Drive" that are offered by Ubuntu's desktop environment, in particular that there is more to "Safely Remove Drive" than just an unmount. With respect to the latter see also




  • this question by k.Cyborg,


  • this answer to it by Sergiy Kolodyazhnyy,


  • this question by LGenzelis,


  • this comment by Tim Kennedy.



Many contributions take the view that it is "safe to remove" an external storage device as soon as it is unmounted. Here some examples:




  • This answer by Patrick,


  • this answer by depquid,


  • this answer by Ignacio Vazquez-Abrams,


  • this comment by xhienne.



Some contributions focus on spinning down external HDDs in addition to an unmount. See for example this question by winchendonsprings. In this comment, sourcejedi points out that spinning down an USB drive reduces its vulnerability to mechanical disturbances.



Others aim on powering off USB drives:




  • This post by bash,


  • this answer by Tony George.



In the following contributions, on-drive caches are explicitly mentioned with respect to "safe removal" of storage devices:




  • This answer by Michael Hamilton,


  • this answer by Totor,


  • this web page by Yan Li,


  • this comment by ack.



The latter is the only contribution I have found that points out the damage that can arise due to wrong assumptions of the kernel with respect to external on-drive write caching. This is exactly the focus of this question. According to that comment, simply unmounting the drive is not enough to prevent that damage. Further details and possible ways to do it right would be highly appreciated.










share|improve this question





























    1















    Abstract



    Sometimes, the Linux kernel is not aware of on-drive write caches of external USB storage devices. Is it necessary in such situations to explicitly flush those caches prior detaching these devices?



    Example



    I use a WD Elements external USB HDD of which hdparm -I says



    ...
    Commands/features:
    Enabled Supported:
    ...
    * Write cache
    ...


    and hdparm -W:



    ...
    write-caching = 1 (on)


    On the other hand, when I plug in the drive, I get the following kernel messages for it:



    ... No Caching mode page found
    ... Assuming drive cache: write through


    According to this answer by Kyle Jones, these kernel messages indicate that the kernel assumes that its write operations will go directly to the platter.



    The section "write_cache (RW)" of the file Documentation/block/queue-sysfs.txt in the Linux Kernel Documentation describes an implication of the kernel assuming a write through cache mode (thanks to Wayne Conrad):




    ... "write through", ... will also eliminate cache flushes issued by
    the kernel.




    Questions



    Up to now, my standard method to detach external USB storage devices from a Linux system was to unmount all mounted partitions on it, to wait until the drive's LED stops flashing, to physically unplug the USB connector, and if this does not power down the device (some have a separate power supply), to explicitly power it down.



    Is this method safe, or does it imply the risk of loosing unflushed data in the on-drive write cache, in particular if the kernel is unaware of that cache?



    In the latter case, it seems to be advisable to explicitly flush the on-drive write cache after the unmount by sending an SCSI sync command. This can be done for example using sg_sync which comes with the sg3-utils:



    sg_sync <device>


    Would this solve the problem? Or should this be supplemented by an SCSI stop command to the device?



    The latter could be issued with (again sg3-utils):



    sg_start 0 -r <device>


    Are sg_sync and sg_start the right tools for this purpose or is it better to use one of the tools and methods that I mention below in section "Related methods" or to do something else to handle the problem?



    To point out the relevance of this question, see this comment by ack.



    Please note: I am not looking for a method to primarily spin down or power off a HDD by software—unplugging the drive and using power switches have proven to be rather reliable in this respect. Instead, I am looking for a method that guarantees that all written data have made it to a non-volatile storage prior the drive is shut down, including data that was cached on-drive.



    Related methods



    In the following, I give some comments on methods that I found to be related to flushing on-drive caches or, more general, to "safe removal" of removable storage devices. There, one aspect is the availability of the involved tools on existing Linux systems. This matters because it is not always possible to simply install missing software.



    Desktop environment: Some desktop environments offer widgets to "safely remove" external USB storage devices. See for example these questions:




    • "Eject / safely remove vs umount" by LGenzelis,


    • "How works the "eject usb driver" from Gnome?" by k.Cyborg.



    and related posts.



    Depending on the implementation, these widgets seem to power down the devices, but I did not find any reference that clarifies whether they cause the devices to flush their caches beforehand, especially in cases in which the kernel is not aware of external on-drive caches.



    In addition, many Linux systems (for example pure servers) do not have any desktop environment installed. So this method is not always available.



    udisks: According to this answer by jimmij, udisks by Freedesktop.org can be used from the command line to "safely remove" an external USB storage device:



    udisks --unmount /dev/sda1
    udisks --detach /dev/sda


    This excellent answer by Totor describes what the udisks --detach command does:





    • sends SCSI sync-cache command,

    • sends SCSI stop command,

    • unbinds the usb-storage kernel driver,

    • suspends the USB device (power),

    • logically disables/removes it from its USB port.




    So it explicitly takes care of the on-drive caches. However, udisks is only available on about one half of the Linux systems I have to deal with.



    udisksctl: Recent versions of udisks provide for the program udisksctl, that can be used for a substitute of the udisks commands shown above. This is again according to jimmij's answer:



    udisksctl unmount -b <partition>
    udisksctl power-off -b <device>


    The same answer also cites the description of the power-off command in the udisksctl(1) man page:




    power-off



    Arranges for the drive to be safely removed and powered off. On the OS
    side this includes ensuring that no process is using the drive, then
    requesting that in-flight buffers and caches are committed to stable
    storage.




    Unfortunately this does not specify whether the "in-flight buffers and caches" includes external on-drive caches that the kernel is not aware of. But it is likely that udisksctl follows its predecessor udisks in this respect.



    Unfortunately, udisksctl definitely does follow its predecessor with respect to its rather low availability on existing systems (compared to the availability of umount, for example).



    eject: According to its man page, the command line tool eject can be used to eject removable media under software control. Affected partitions will be unmounted beforehand as needed.



    Albeit this tool shows up in several discussions on "safe removal" of removable media, see for example this question by LGenzelis and this question by k.Cyborg, nothing indicates that it does more than an unmount in this respect.



    In addition, I suspect that this tool focuses more on media and media trays than on devices. This might be the reason why it simply dies with the error message



    eject: unable to eject


    when it is applied on the WD Elements USB drive that I mentioned as the introductory example above. However, it succeeds on some USB memory sticks.



    Nevertheless, as a part of the linux-utils, this tool is highly available.



    sg3-utils: The programs sg_sync and sg_start were already discussed above.



    This comment by quirks to an Ubuntu bug report indicates that udisks internally uses the sg3-utils to send its SCSI sync and stop commands to the device.



    It seems to me that the sg3-utils have a wider availability than udisks. But this is only a vague and personal impression.



    sdparm: This web page by Yan Li discusses a procedure to "Safely remove an USB hard drive in Linux". For that purpose, it recommends a script that in principle uses the following sdparm commands to flush on-drive caches and to stop (spin down?) the USB HDD:



    sdparm --command=sync <device>
    sdparm --command=stop <device>


    These seem to be comparable to the sg_sync and sg_start commands discussed above, and might be used as a substitute for the latter.



    hdparm: Being basically a tool to manage ATA drives, hdparm is in some sense a foreign object when it comes to USB drives, because the latter are primarily addressed as SCSI devices in Linux. In cases like our WD Elements example, there is an ATA HDD sitting behind an SCSI to ATA translation layer (SAT layer). See this answer by Mikko Rantalainen for more details. Depending on the SAT's implementation, hdparm can be used with limited functionality to manipulate these drives.



    If supported, one can use the commands



    hdparm -F <device>
    hdparm -Y <device>


    to flush the on-drive caches and to stop the drives. If this is not possible, one might think of using



    hdparm -W0 <device>


    as a workaround to flush the caches. But beware: This command is actually intended to switch the on-drive write caching off. Therefore one should make sure that it actually flushes rather than simply drops the cache contents that was accumulated up to now.



    For the WD Elements drive, none of these commands work: Instead they report bad/missing sense data.



    sysfs: Scattered over the web, there are recipes to unbind an external USB drive from its driver, to unregister the drive from the system, or to power it down by manipulating device attributes that the Linux kernel exposes in its sysfs.



    Here is an example from this post by bash in the Debian forum:



    echo "auto" > "/sys/bus/usb/devices/usb1/1-5/power/level"
    echo "1-5:1.0" > /sys/bus/usb/devices/1-5:1.0/driver/unbind


    and



    echo "1" > "/sys/bus/usb/devices/usb1/1-5/remove"


    Or from this answer by Tony George:



    echo 'offline' > /sys/block/sdb/device/state
    echo '1' > /sys/block/sdb/device/delete


    I have too little knowledge about the concepts that the kernel developers had in mind regarding the usage of these attributes to be able to judge these code snippets. But I have some doubt that they are helpful to flush on-drive write caches that the kernel is not aware of.



    In addition, it seems that at least some of these recipes are outdated. In this respect, see the first paragraph of the "Sysfs Rules" in the kernel documentation as of 2019-01-25:




    The kernel-exported sysfs exports internal kernel implementation
    details and depends on internal kernel structures and layout. It is
    agreed upon by the kernel developers that the Linux kernel does not
    provide a stable internal API. Therefore, there are aspects of the
    sysfs interface that may not be stable across kernel releases.




    Umount and wait: This is the method that I referred to in my question above: It comprises an unmount and a subsequent waiting until the (presumably) write activities on the drive have finally ceased. The next and final step is to hope that the on-drive write caches were flushed in the course of that.



    It is the main point of this question to clarify whether this is a safe method (for the data).



    In any case, this method has the big advantage that it is easy, it is available on any Linux system I know, and the syntax of the umount command did not change over decades.



    Further reading



    Some general discussions about "ejecting" and "safe removal" of USB or other external storage devices can be found in the context of these questions:




    • "Safest way to remove USB drive on Linux [duplicate]" by Pkkm,


    • "Eject USB drives / eject command" by Joe Barr,


    • "When is it safe to disconnect my external HDD?" by jcora.



    In addition, Luis Alvarado describes in this answer the differences between the options "Unmount", "Eject", and "Safely Remove Drive" that are offered by Ubuntu's desktop environment, in particular that there is more to "Safely Remove Drive" than just an unmount. With respect to the latter see also




    • this question by k.Cyborg,


    • this answer to it by Sergiy Kolodyazhnyy,


    • this question by LGenzelis,


    • this comment by Tim Kennedy.



    Many contributions take the view that it is "safe to remove" an external storage device as soon as it is unmounted. Here some examples:




    • This answer by Patrick,


    • this answer by depquid,


    • this answer by Ignacio Vazquez-Abrams,


    • this comment by xhienne.



    Some contributions focus on spinning down external HDDs in addition to an unmount. See for example this question by winchendonsprings. In this comment, sourcejedi points out that spinning down an USB drive reduces its vulnerability to mechanical disturbances.



    Others aim on powering off USB drives:




    • This post by bash,


    • this answer by Tony George.



    In the following contributions, on-drive caches are explicitly mentioned with respect to "safe removal" of storage devices:




    • This answer by Michael Hamilton,


    • this answer by Totor,


    • this web page by Yan Li,


    • this comment by ack.



    The latter is the only contribution I have found that points out the damage that can arise due to wrong assumptions of the kernel with respect to external on-drive write caching. This is exactly the focus of this question. According to that comment, simply unmounting the drive is not enough to prevent that damage. Further details and possible ways to do it right would be highly appreciated.










    share|improve this question



























      1












      1








      1








      Abstract



      Sometimes, the Linux kernel is not aware of on-drive write caches of external USB storage devices. Is it necessary in such situations to explicitly flush those caches prior detaching these devices?



      Example



      I use a WD Elements external USB HDD of which hdparm -I says



      ...
      Commands/features:
      Enabled Supported:
      ...
      * Write cache
      ...


      and hdparm -W:



      ...
      write-caching = 1 (on)


      On the other hand, when I plug in the drive, I get the following kernel messages for it:



      ... No Caching mode page found
      ... Assuming drive cache: write through


      According to this answer by Kyle Jones, these kernel messages indicate that the kernel assumes that its write operations will go directly to the platter.



      The section "write_cache (RW)" of the file Documentation/block/queue-sysfs.txt in the Linux Kernel Documentation describes an implication of the kernel assuming a write through cache mode (thanks to Wayne Conrad):




      ... "write through", ... will also eliminate cache flushes issued by
      the kernel.




      Questions



      Up to now, my standard method to detach external USB storage devices from a Linux system was to unmount all mounted partitions on it, to wait until the drive's LED stops flashing, to physically unplug the USB connector, and if this does not power down the device (some have a separate power supply), to explicitly power it down.



      Is this method safe, or does it imply the risk of loosing unflushed data in the on-drive write cache, in particular if the kernel is unaware of that cache?



      In the latter case, it seems to be advisable to explicitly flush the on-drive write cache after the unmount by sending an SCSI sync command. This can be done for example using sg_sync which comes with the sg3-utils:



      sg_sync <device>


      Would this solve the problem? Or should this be supplemented by an SCSI stop command to the device?



      The latter could be issued with (again sg3-utils):



      sg_start 0 -r <device>


      Are sg_sync and sg_start the right tools for this purpose or is it better to use one of the tools and methods that I mention below in section "Related methods" or to do something else to handle the problem?



      To point out the relevance of this question, see this comment by ack.



      Please note: I am not looking for a method to primarily spin down or power off a HDD by software—unplugging the drive and using power switches have proven to be rather reliable in this respect. Instead, I am looking for a method that guarantees that all written data have made it to a non-volatile storage prior the drive is shut down, including data that was cached on-drive.



      Related methods



      In the following, I give some comments on methods that I found to be related to flushing on-drive caches or, more general, to "safe removal" of removable storage devices. There, one aspect is the availability of the involved tools on existing Linux systems. This matters because it is not always possible to simply install missing software.



      Desktop environment: Some desktop environments offer widgets to "safely remove" external USB storage devices. See for example these questions:




      • "Eject / safely remove vs umount" by LGenzelis,


      • "How works the "eject usb driver" from Gnome?" by k.Cyborg.



      and related posts.



      Depending on the implementation, these widgets seem to power down the devices, but I did not find any reference that clarifies whether they cause the devices to flush their caches beforehand, especially in cases in which the kernel is not aware of external on-drive caches.



      In addition, many Linux systems (for example pure servers) do not have any desktop environment installed. So this method is not always available.



      udisks: According to this answer by jimmij, udisks by Freedesktop.org can be used from the command line to "safely remove" an external USB storage device:



      udisks --unmount /dev/sda1
      udisks --detach /dev/sda


      This excellent answer by Totor describes what the udisks --detach command does:





      • sends SCSI sync-cache command,

      • sends SCSI stop command,

      • unbinds the usb-storage kernel driver,

      • suspends the USB device (power),

      • logically disables/removes it from its USB port.




      So it explicitly takes care of the on-drive caches. However, udisks is only available on about one half of the Linux systems I have to deal with.



      udisksctl: Recent versions of udisks provide for the program udisksctl, that can be used for a substitute of the udisks commands shown above. This is again according to jimmij's answer:



      udisksctl unmount -b <partition>
      udisksctl power-off -b <device>


      The same answer also cites the description of the power-off command in the udisksctl(1) man page:




      power-off



      Arranges for the drive to be safely removed and powered off. On the OS
      side this includes ensuring that no process is using the drive, then
      requesting that in-flight buffers and caches are committed to stable
      storage.




      Unfortunately this does not specify whether the "in-flight buffers and caches" includes external on-drive caches that the kernel is not aware of. But it is likely that udisksctl follows its predecessor udisks in this respect.



      Unfortunately, udisksctl definitely does follow its predecessor with respect to its rather low availability on existing systems (compared to the availability of umount, for example).



      eject: According to its man page, the command line tool eject can be used to eject removable media under software control. Affected partitions will be unmounted beforehand as needed.



      Albeit this tool shows up in several discussions on "safe removal" of removable media, see for example this question by LGenzelis and this question by k.Cyborg, nothing indicates that it does more than an unmount in this respect.



      In addition, I suspect that this tool focuses more on media and media trays than on devices. This might be the reason why it simply dies with the error message



      eject: unable to eject


      when it is applied on the WD Elements USB drive that I mentioned as the introductory example above. However, it succeeds on some USB memory sticks.



      Nevertheless, as a part of the linux-utils, this tool is highly available.



      sg3-utils: The programs sg_sync and sg_start were already discussed above.



      This comment by quirks to an Ubuntu bug report indicates that udisks internally uses the sg3-utils to send its SCSI sync and stop commands to the device.



      It seems to me that the sg3-utils have a wider availability than udisks. But this is only a vague and personal impression.



      sdparm: This web page by Yan Li discusses a procedure to "Safely remove an USB hard drive in Linux". For that purpose, it recommends a script that in principle uses the following sdparm commands to flush on-drive caches and to stop (spin down?) the USB HDD:



      sdparm --command=sync <device>
      sdparm --command=stop <device>


      These seem to be comparable to the sg_sync and sg_start commands discussed above, and might be used as a substitute for the latter.



      hdparm: Being basically a tool to manage ATA drives, hdparm is in some sense a foreign object when it comes to USB drives, because the latter are primarily addressed as SCSI devices in Linux. In cases like our WD Elements example, there is an ATA HDD sitting behind an SCSI to ATA translation layer (SAT layer). See this answer by Mikko Rantalainen for more details. Depending on the SAT's implementation, hdparm can be used with limited functionality to manipulate these drives.



      If supported, one can use the commands



      hdparm -F <device>
      hdparm -Y <device>


      to flush the on-drive caches and to stop the drives. If this is not possible, one might think of using



      hdparm -W0 <device>


      as a workaround to flush the caches. But beware: This command is actually intended to switch the on-drive write caching off. Therefore one should make sure that it actually flushes rather than simply drops the cache contents that was accumulated up to now.



      For the WD Elements drive, none of these commands work: Instead they report bad/missing sense data.



      sysfs: Scattered over the web, there are recipes to unbind an external USB drive from its driver, to unregister the drive from the system, or to power it down by manipulating device attributes that the Linux kernel exposes in its sysfs.



      Here is an example from this post by bash in the Debian forum:



      echo "auto" > "/sys/bus/usb/devices/usb1/1-5/power/level"
      echo "1-5:1.0" > /sys/bus/usb/devices/1-5:1.0/driver/unbind


      and



      echo "1" > "/sys/bus/usb/devices/usb1/1-5/remove"


      Or from this answer by Tony George:



      echo 'offline' > /sys/block/sdb/device/state
      echo '1' > /sys/block/sdb/device/delete


      I have too little knowledge about the concepts that the kernel developers had in mind regarding the usage of these attributes to be able to judge these code snippets. But I have some doubt that they are helpful to flush on-drive write caches that the kernel is not aware of.



      In addition, it seems that at least some of these recipes are outdated. In this respect, see the first paragraph of the "Sysfs Rules" in the kernel documentation as of 2019-01-25:




      The kernel-exported sysfs exports internal kernel implementation
      details and depends on internal kernel structures and layout. It is
      agreed upon by the kernel developers that the Linux kernel does not
      provide a stable internal API. Therefore, there are aspects of the
      sysfs interface that may not be stable across kernel releases.




      Umount and wait: This is the method that I referred to in my question above: It comprises an unmount and a subsequent waiting until the (presumably) write activities on the drive have finally ceased. The next and final step is to hope that the on-drive write caches were flushed in the course of that.



      It is the main point of this question to clarify whether this is a safe method (for the data).



      In any case, this method has the big advantage that it is easy, it is available on any Linux system I know, and the syntax of the umount command did not change over decades.



      Further reading



      Some general discussions about "ejecting" and "safe removal" of USB or other external storage devices can be found in the context of these questions:




      • "Safest way to remove USB drive on Linux [duplicate]" by Pkkm,


      • "Eject USB drives / eject command" by Joe Barr,


      • "When is it safe to disconnect my external HDD?" by jcora.



      In addition, Luis Alvarado describes in this answer the differences between the options "Unmount", "Eject", and "Safely Remove Drive" that are offered by Ubuntu's desktop environment, in particular that there is more to "Safely Remove Drive" than just an unmount. With respect to the latter see also




      • this question by k.Cyborg,


      • this answer to it by Sergiy Kolodyazhnyy,


      • this question by LGenzelis,


      • this comment by Tim Kennedy.



      Many contributions take the view that it is "safe to remove" an external storage device as soon as it is unmounted. Here some examples:




      • This answer by Patrick,


      • this answer by depquid,


      • this answer by Ignacio Vazquez-Abrams,


      • this comment by xhienne.



      Some contributions focus on spinning down external HDDs in addition to an unmount. See for example this question by winchendonsprings. In this comment, sourcejedi points out that spinning down an USB drive reduces its vulnerability to mechanical disturbances.



      Others aim on powering off USB drives:




      • This post by bash,


      • this answer by Tony George.



      In the following contributions, on-drive caches are explicitly mentioned with respect to "safe removal" of storage devices:




      • This answer by Michael Hamilton,


      • this answer by Totor,


      • this web page by Yan Li,


      • this comment by ack.



      The latter is the only contribution I have found that points out the damage that can arise due to wrong assumptions of the kernel with respect to external on-drive write caching. This is exactly the focus of this question. According to that comment, simply unmounting the drive is not enough to prevent that damage. Further details and possible ways to do it right would be highly appreciated.










      share|improve this question
















      Abstract



      Sometimes, the Linux kernel is not aware of on-drive write caches of external USB storage devices. Is it necessary in such situations to explicitly flush those caches prior detaching these devices?



      Example



      I use a WD Elements external USB HDD of which hdparm -I says



      ...
      Commands/features:
      Enabled Supported:
      ...
      * Write cache
      ...


      and hdparm -W:



      ...
      write-caching = 1 (on)


      On the other hand, when I plug in the drive, I get the following kernel messages for it:



      ... No Caching mode page found
      ... Assuming drive cache: write through


      According to this answer by Kyle Jones, these kernel messages indicate that the kernel assumes that its write operations will go directly to the platter.



      The section "write_cache (RW)" of the file Documentation/block/queue-sysfs.txt in the Linux Kernel Documentation describes an implication of the kernel assuming a write through cache mode (thanks to Wayne Conrad):




      ... "write through", ... will also eliminate cache flushes issued by
      the kernel.




      Questions



      Up to now, my standard method to detach external USB storage devices from a Linux system was to unmount all mounted partitions on it, to wait until the drive's LED stops flashing, to physically unplug the USB connector, and if this does not power down the device (some have a separate power supply), to explicitly power it down.



      Is this method safe, or does it imply the risk of loosing unflushed data in the on-drive write cache, in particular if the kernel is unaware of that cache?



      In the latter case, it seems to be advisable to explicitly flush the on-drive write cache after the unmount by sending an SCSI sync command. This can be done for example using sg_sync which comes with the sg3-utils:



      sg_sync <device>


      Would this solve the problem? Or should this be supplemented by an SCSI stop command to the device?



      The latter could be issued with (again sg3-utils):



      sg_start 0 -r <device>


      Are sg_sync and sg_start the right tools for this purpose or is it better to use one of the tools and methods that I mention below in section "Related methods" or to do something else to handle the problem?



      To point out the relevance of this question, see this comment by ack.



      Please note: I am not looking for a method to primarily spin down or power off a HDD by software—unplugging the drive and using power switches have proven to be rather reliable in this respect. Instead, I am looking for a method that guarantees that all written data have made it to a non-volatile storage prior the drive is shut down, including data that was cached on-drive.



      Related methods



      In the following, I give some comments on methods that I found to be related to flushing on-drive caches or, more general, to "safe removal" of removable storage devices. There, one aspect is the availability of the involved tools on existing Linux systems. This matters because it is not always possible to simply install missing software.



      Desktop environment: Some desktop environments offer widgets to "safely remove" external USB storage devices. See for example these questions:




      • "Eject / safely remove vs umount" by LGenzelis,


      • "How works the "eject usb driver" from Gnome?" by k.Cyborg.



      and related posts.



      Depending on the implementation, these widgets seem to power down the devices, but I did not find any reference that clarifies whether they cause the devices to flush their caches beforehand, especially in cases in which the kernel is not aware of external on-drive caches.



      In addition, many Linux systems (for example pure servers) do not have any desktop environment installed. So this method is not always available.



      udisks: According to this answer by jimmij, udisks by Freedesktop.org can be used from the command line to "safely remove" an external USB storage device:



      udisks --unmount /dev/sda1
      udisks --detach /dev/sda


      This excellent answer by Totor describes what the udisks --detach command does:





      • sends SCSI sync-cache command,

      • sends SCSI stop command,

      • unbinds the usb-storage kernel driver,

      • suspends the USB device (power),

      • logically disables/removes it from its USB port.




      So it explicitly takes care of the on-drive caches. However, udisks is only available on about one half of the Linux systems I have to deal with.



      udisksctl: Recent versions of udisks provide for the program udisksctl, that can be used for a substitute of the udisks commands shown above. This is again according to jimmij's answer:



      udisksctl unmount -b <partition>
      udisksctl power-off -b <device>


      The same answer also cites the description of the power-off command in the udisksctl(1) man page:




      power-off



      Arranges for the drive to be safely removed and powered off. On the OS
      side this includes ensuring that no process is using the drive, then
      requesting that in-flight buffers and caches are committed to stable
      storage.




      Unfortunately this does not specify whether the "in-flight buffers and caches" includes external on-drive caches that the kernel is not aware of. But it is likely that udisksctl follows its predecessor udisks in this respect.



      Unfortunately, udisksctl definitely does follow its predecessor with respect to its rather low availability on existing systems (compared to the availability of umount, for example).



      eject: According to its man page, the command line tool eject can be used to eject removable media under software control. Affected partitions will be unmounted beforehand as needed.



      Albeit this tool shows up in several discussions on "safe removal" of removable media, see for example this question by LGenzelis and this question by k.Cyborg, nothing indicates that it does more than an unmount in this respect.



      In addition, I suspect that this tool focuses more on media and media trays than on devices. This might be the reason why it simply dies with the error message



      eject: unable to eject


      when it is applied on the WD Elements USB drive that I mentioned as the introductory example above. However, it succeeds on some USB memory sticks.



      Nevertheless, as a part of the linux-utils, this tool is highly available.



      sg3-utils: The programs sg_sync and sg_start were already discussed above.



      This comment by quirks to an Ubuntu bug report indicates that udisks internally uses the sg3-utils to send its SCSI sync and stop commands to the device.



      It seems to me that the sg3-utils have a wider availability than udisks. But this is only a vague and personal impression.



      sdparm: This web page by Yan Li discusses a procedure to "Safely remove an USB hard drive in Linux". For that purpose, it recommends a script that in principle uses the following sdparm commands to flush on-drive caches and to stop (spin down?) the USB HDD:



      sdparm --command=sync <device>
      sdparm --command=stop <device>


      These seem to be comparable to the sg_sync and sg_start commands discussed above, and might be used as a substitute for the latter.



      hdparm: Being basically a tool to manage ATA drives, hdparm is in some sense a foreign object when it comes to USB drives, because the latter are primarily addressed as SCSI devices in Linux. In cases like our WD Elements example, there is an ATA HDD sitting behind an SCSI to ATA translation layer (SAT layer). See this answer by Mikko Rantalainen for more details. Depending on the SAT's implementation, hdparm can be used with limited functionality to manipulate these drives.



      If supported, one can use the commands



      hdparm -F <device>
      hdparm -Y <device>


      to flush the on-drive caches and to stop the drives. If this is not possible, one might think of using



      hdparm -W0 <device>


      as a workaround to flush the caches. But beware: This command is actually intended to switch the on-drive write caching off. Therefore one should make sure that it actually flushes rather than simply drops the cache contents that was accumulated up to now.



      For the WD Elements drive, none of these commands work: Instead they report bad/missing sense data.



      sysfs: Scattered over the web, there are recipes to unbind an external USB drive from its driver, to unregister the drive from the system, or to power it down by manipulating device attributes that the Linux kernel exposes in its sysfs.



      Here is an example from this post by bash in the Debian forum:



      echo "auto" > "/sys/bus/usb/devices/usb1/1-5/power/level"
      echo "1-5:1.0" > /sys/bus/usb/devices/1-5:1.0/driver/unbind


      and



      echo "1" > "/sys/bus/usb/devices/usb1/1-5/remove"


      Or from this answer by Tony George:



      echo 'offline' > /sys/block/sdb/device/state
      echo '1' > /sys/block/sdb/device/delete


      I have too little knowledge about the concepts that the kernel developers had in mind regarding the usage of these attributes to be able to judge these code snippets. But I have some doubt that they are helpful to flush on-drive write caches that the kernel is not aware of.



      In addition, it seems that at least some of these recipes are outdated. In this respect, see the first paragraph of the "Sysfs Rules" in the kernel documentation as of 2019-01-25:




      The kernel-exported sysfs exports internal kernel implementation
      details and depends on internal kernel structures and layout. It is
      agreed upon by the kernel developers that the Linux kernel does not
      provide a stable internal API. Therefore, there are aspects of the
      sysfs interface that may not be stable across kernel releases.




      Umount and wait: This is the method that I referred to in my question above: It comprises an unmount and a subsequent waiting until the (presumably) write activities on the drive have finally ceased. The next and final step is to hope that the on-drive write caches were flushed in the course of that.



      It is the main point of this question to clarify whether this is a safe method (for the data).



      In any case, this method has the big advantage that it is easy, it is available on any Linux system I know, and the syntax of the umount command did not change over decades.



      Further reading



      Some general discussions about "ejecting" and "safe removal" of USB or other external storage devices can be found in the context of these questions:




      • "Safest way to remove USB drive on Linux [duplicate]" by Pkkm,


      • "Eject USB drives / eject command" by Joe Barr,


      • "When is it safe to disconnect my external HDD?" by jcora.



      In addition, Luis Alvarado describes in this answer the differences between the options "Unmount", "Eject", and "Safely Remove Drive" that are offered by Ubuntu's desktop environment, in particular that there is more to "Safely Remove Drive" than just an unmount. With respect to the latter see also




      • this question by k.Cyborg,


      • this answer to it by Sergiy Kolodyazhnyy,


      • this question by LGenzelis,


      • this comment by Tim Kennedy.



      Many contributions take the view that it is "safe to remove" an external storage device as soon as it is unmounted. Here some examples:




      • This answer by Patrick,


      • this answer by depquid,


      • this answer by Ignacio Vazquez-Abrams,


      • this comment by xhienne.



      Some contributions focus on spinning down external HDDs in addition to an unmount. See for example this question by winchendonsprings. In this comment, sourcejedi points out that spinning down an USB drive reduces its vulnerability to mechanical disturbances.



      Others aim on powering off USB drives:




      • This post by bash,


      • this answer by Tony George.



      In the following contributions, on-drive caches are explicitly mentioned with respect to "safe removal" of storage devices:




      • This answer by Michael Hamilton,


      • this answer by Totor,


      • this web page by Yan Li,


      • this comment by ack.



      The latter is the only contribution I have found that points out the damage that can arise due to wrong assumptions of the kernel with respect to external on-drive write caching. This is exactly the focus of this question. According to that comment, simply unmounting the drive is not enough to prevent that damage. Further details and possible ways to do it right would be highly appreciated.







      linux command-line usb cache unmounting






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 25 at 23:38







      Jürgen

















      asked Jan 20 at 23:10









      JürgenJürgen

      1268




      1268






















          0






          active

          oldest

          votes











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f495670%2fis-it-necessary-to-explicitly-flush-the-hdd-on-disk-write-caches%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Unix & Linux Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f495670%2fis-it-necessary-to-explicitly-flush-the-hdd-on-disk-write-caches%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?