tuxonice_highlevel.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374
  1. /*
  2. * kernel/power/tuxonice_highlevel.c
  3. */
  4. /** \mainpage TuxOnIce.
  5. *
  6. * TuxOnIce provides support for saving and restoring an image of
  7. * system memory to an arbitrary storage device, either on the local computer,
  8. * or across some network. The support is entirely OS based, so TuxOnIce
  9. * works without requiring BIOS, APM or ACPI support. The vast majority of the
  10. * code is also architecture independent, so it should be very easy to port
  11. * the code to new architectures. TuxOnIce includes support for SMP, 4G HighMem
  12. * and preemption. Initramfses and initrds are also supported.
  13. *
  14. * TuxOnIce uses a modular design, in which the method of storing the image is
  15. * completely abstracted from the core code, as are transformations on the data
  16. * such as compression and/or encryption (multiple 'modules' can be used to
  17. * provide arbitrary combinations of functionality). The user interface is also
  18. * modular, so that arbitrarily simple or complex interfaces can be used to
  19. * provide anything from debugging information through to eye candy.
  20. *
  21. * \section Copyright
  22. *
  23. * TuxOnIce is released under the GPLv2.
  24. *
  25. * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu><BR>
  26. * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz><BR>
  27. * Copyright (C) 2002-2003 Florent Chabaud <fchabaud@free.fr><BR>
  28. * Copyright (C) 2002-2014 Nigel Cunningham (nigel at tuxonice net)<BR>
  29. *
  30. * \section Credits
  31. *
  32. * Nigel would like to thank the following people for their work:
  33. *
  34. * Bernard Blackham <bernard@blackham.com.au><BR>
  35. * Web page & Wiki administration, some coding. A person without whom
  36. * TuxOnIce would not be where it is.
  37. *
  38. * Michael Frank <mhf@linuxmail.org><BR>
  39. * Extensive testing and help with improving stability. I was constantly
  40. * amazed by the quality and quantity of Michael's help.
  41. *
  42. * Pavel Machek <pavel@ucw.cz><BR>
  43. * Modifications, defectiveness pointing, being with Gabor at the very
  44. * beginning, suspend to swap space, stop all tasks. Port to 2.4.18-ac and
  45. * 2.5.17. Even though Pavel and I disagree on the direction suspend to
  46. * disk should take, I appreciate the valuable work he did in helping Gabor
  47. * get the concept working.
  48. *
  49. * ..and of course the myriads of TuxOnIce users who have helped diagnose
  50. * and fix bugs, made suggestions on how to improve the code, proofread
  51. * documentation, and donated time and money.
  52. *
  53. * Thanks also to corporate sponsors:
  54. *
  55. * <B>Redhat.</B>Sometime employer from May 2006 (my fault, not Redhat's!).
  56. *
  57. * <B>Cyclades.com.</B> Nigel's employers from Dec 2004 until May 2006, who
  58. * allowed him to work on TuxOnIce and PM related issues on company time.
  59. *
  60. * <B>LinuxFund.org.</B> Sponsored Nigel's work on TuxOnIce for four months Oct
  61. * 2003 to Jan 2004.
  62. *
  63. * <B>LAC Linux.</B> Donated P4 hardware that enabled development and ongoing
  64. * maintenance of SMP and Highmem support.
  65. *
  66. * <B>OSDL.</B> Provided access to various hardware configurations, make
  67. * occasional small donations to the project.
  68. */
  69. #include <linux/suspend.h>
  70. #include <linux/freezer.h>
  71. #include <generated/utsrelease.h>
  72. #include <linux/cpu.h>
  73. #include <linux/console.h>
  74. #include <linux/writeback.h>
  75. #include <linux/uaccess.h> /* for get/set_fs & KERNEL_DS on i386 */
  76. #include <linux/bio.h>
  77. #include <linux/kgdb.h>
  78. #include "tuxonice.h"
  79. #include "tuxonice_modules.h"
  80. #include "tuxonice_sysfs.h"
  81. #include "tuxonice_prepare_image.h"
  82. #include "tuxonice_io.h"
  83. #include "tuxonice_ui.h"
  84. #include "tuxonice_power_off.h"
  85. #include "tuxonice_storage.h"
  86. #include "tuxonice_checksum.h"
  87. #include "tuxonice_builtin.h"
  88. #include "tuxonice_atomic_copy.h"
  89. #include "tuxonice_alloc.h"
  90. #include "tuxonice_cluster.h"
  91. /*! Pageset metadata. */
  92. struct pagedir pagedir2 = { 2 };
  93. EXPORT_SYMBOL_GPL(pagedir2);
  94. static mm_segment_t oldfs;
  95. static DEFINE_MUTEX(tuxonice_in_use);
  96. static int block_dump_save;
  97. int toi_trace_index;
  98. /* Binary signature if an image is present */
  99. char tuxonice_signature[9] = "\xed\xc3\x02\xe9\x98\x56\xe5\x0c";
  100. EXPORT_SYMBOL_GPL(tuxonice_signature);
  101. unsigned long boot_kernel_data_buffer;
  102. #ifdef CONFIG_TOI_FIXUP
  103. #if 0 /* removed it */
  104. #endif
  105. static char *result_strings[] = {
  106. "Hibernation was aborted",
  107. "The user requested that we cancel the hibernation",
  108. "No storage was available",
  109. "Insufficient storage was available",
  110. "Freezing filesystems and/or tasks failed",
  111. "A pre-existing image was used",
  112. "We would free memory, but image size limit doesn't allow this",
  113. "Unable to free enough memory to hibernate",
  114. "Unable to obtain the Power Management Semaphore",
  115. "A device suspend/resume returned an error",
  116. "A system device suspend/resume returned an error",
  117. "The extra pages allowance is too small",
  118. "We were unable to successfully prepare an image",
  119. "TuxOnIce module initialisation failed",
  120. "TuxOnIce module cleanup failed",
  121. "I/O errors were encountered",
  122. "Ran out of memory",
  123. "An error was encountered while reading the image",
  124. "Platform preparation failed",
  125. "CPU Hotplugging failed",
  126. "Architecture specific preparation failed",
  127. "Pages needed resaving, but we were told to abort if this happens",
  128. "We can't hibernate at the moment (invalid resume= or filewriter " "target?)",
  129. "A hibernation preparation notifier chain member cancelled the " "hibernation",
  130. "Pre-snapshot preparation failed",
  131. "Pre-restore preparation failed",
  132. "Failed to disable usermode helpers",
  133. "Can't resume from alternate image",
  134. "Header reservation too small",
  135. "Device Power Management Preparation failed",
  136. };
  137. #ifdef CONFIG_TOI_FIXUP
  138. #endif /* remove it */
  139. #endif
  140. /**
  141. * toi_finish_anything - cleanup after doing anything
  142. * @hibernate_or_resume: Whether finishing a cycle or attempt at
  143. * resuming.
  144. *
  145. * This is our basic clean-up routine, matching start_anything below. We
  146. * call cleanup routines, drop module references and restore process fs and
  147. * cpus allowed masks, together with the global block_dump variable's value.
  148. **/
  149. void toi_finish_anything(int hibernate_or_resume)
  150. {
  151. hib_log("hibernate_or_resume(%d)\n", hibernate_or_resume);
  152. toi_running = 0;
  153. toi_cleanup_modules(hibernate_or_resume);
  154. toi_put_modules();
  155. if (hibernate_or_resume) {
  156. block_dump = block_dump_save;
  157. set_cpus_allowed_ptr(current, cpu_all_mask);
  158. toi_alloc_print_debug_stats();
  159. atomic_inc(&snapshot_device_available);
  160. unlock_system_sleep();
  161. }
  162. set_fs(oldfs);
  163. mutex_unlock(&tuxonice_in_use);
  164. }
  165. /**
  166. * toi_start_anything - basic initialisation for TuxOnIce
  167. * @toi_or_resume: Whether starting a cycle or attempt at resuming.
  168. *
  169. * Our basic initialisation routine. Take references on modules, use the
  170. * kernel segment, recheck resume= if no active allocator is set, initialise
  171. * modules, save and reset block_dump and ensure we're running on CPU0.
  172. **/
  173. int toi_start_anything(int hibernate_or_resume)
  174. {
  175. mutex_lock(&tuxonice_in_use);
  176. oldfs = get_fs();
  177. set_fs(KERNEL_DS);
  178. toi_trace_index = 0;
  179. if (hibernate_or_resume) {
  180. lock_system_sleep();
  181. if (!atomic_add_unless(&snapshot_device_available, -1, 0))
  182. goto snapshotdevice_unavailable;
  183. }
  184. if (hibernate_or_resume == SYSFS_HIBERNATE)
  185. toi_print_modules();
  186. if (toi_get_modules()) {
  187. pr_warn("TuxOnIce: Get modules failed!\n");
  188. goto prehibernate_err;
  189. }
  190. if (hibernate_or_resume) {
  191. block_dump_save = block_dump;
  192. block_dump = 0;
  193. set_cpus_allowed_ptr(current, cpumask_of(cpumask_first(cpu_online_mask)));
  194. }
  195. if (toi_initialise_modules_early(hibernate_or_resume))
  196. goto early_init_err;
  197. if (!toiActiveAllocator) {
  198. hib_log("hibernate_or_resume(0x%08x), resume_file=\"%s\"\n", hibernate_or_resume,
  199. resume_file);
  200. toi_attempt_to_parse_resume_device(!hibernate_or_resume);
  201. }
  202. if (!toi_initialise_modules_late(hibernate_or_resume)) {
  203. toi_running = 1; /* For the swsusp code we use :< */
  204. return 0;
  205. }
  206. toi_cleanup_modules(hibernate_or_resume);
  207. early_init_err:
  208. if (hibernate_or_resume) {
  209. block_dump_save = block_dump;
  210. set_cpus_allowed_ptr(current, cpu_all_mask);
  211. }
  212. toi_put_modules();
  213. prehibernate_err:
  214. if (hibernate_or_resume)
  215. atomic_inc(&snapshot_device_available);
  216. snapshotdevice_unavailable:
  217. if (hibernate_or_resume)
  218. mutex_unlock(&pm_mutex);
  219. set_fs(oldfs);
  220. mutex_unlock(&tuxonice_in_use);
  221. return -EBUSY;
  222. }
  223. /*
  224. * Nosave page tracking.
  225. *
  226. * Here rather than in prepare_image because we want to do it once only at the
  227. * start of a cycle.
  228. */
  229. /**
  230. * mark_nosave_pages - set up our Nosave bitmap
  231. *
  232. * Build a bitmap of Nosave pages from the list. The bitmap allows faster
  233. * use when preparing the image.
  234. **/
  235. static void mark_nosave_pages(void)
  236. {
  237. struct nosave_region *region;
  238. list_for_each_entry(region, &nosave_regions, list) {
  239. unsigned long pfn;
  240. for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++)
  241. if (pfn_valid(pfn))
  242. SetPageNosave(pfn_to_page(pfn));
  243. }
  244. }
  245. /**
  246. * allocate_bitmaps - allocate bitmaps used to record page states
  247. *
  248. * Allocate the bitmaps we use to record the various TuxOnIce related
  249. * page states.
  250. **/
  251. static int allocate_bitmaps(void)
  252. {
  253. if (toi_alloc_bitmap(&pageset1_map) ||
  254. toi_alloc_bitmap(&pageset1_copy_map) ||
  255. toi_alloc_bitmap(&pageset2_map) ||
  256. toi_alloc_bitmap(&io_map) ||
  257. toi_alloc_bitmap(&nosave_map) ||
  258. toi_alloc_bitmap(&free_map) ||
  259. toi_alloc_bitmap(&compare_map) ||
  260. toi_alloc_bitmap(&page_resave_map))
  261. return 1;
  262. return 0;
  263. }
  264. /**
  265. * free_bitmaps - free the bitmaps used to record page states
  266. *
  267. * Free the bitmaps allocated above. It is not an error to call
  268. * memory_bm_free on a bitmap that isn't currently allocated.
  269. **/
  270. static void free_bitmaps(void)
  271. {
  272. toi_free_bitmap(&pageset1_map);
  273. toi_free_bitmap(&pageset1_copy_map);
  274. toi_free_bitmap(&pageset2_map);
  275. toi_free_bitmap(&io_map);
  276. toi_free_bitmap(&nosave_map);
  277. toi_free_bitmap(&free_map);
  278. toi_free_bitmap(&compare_map);
  279. toi_free_bitmap(&page_resave_map);
  280. }
  281. /**
  282. * io_MB_per_second - return the number of MB/s read or written
  283. * @write: Whether to return the speed at which we wrote.
  284. *
  285. * Calculate the number of megabytes per second that were read or written.
  286. **/
  287. static int io_MB_per_second(int write)
  288. {
  289. return (toi_bkd.toi_io_time[write][1]) ?
  290. MB((unsigned long)toi_bkd.toi_io_time[write][0]) * HZ /
  291. toi_bkd.toi_io_time[write][1] : 0;
  292. }
  293. #define SNPRINTF(a...) ((len) += scnprintf(((char *) (buffer)) + (len), (count) - (len) - 1, ##a))
  294. /**
  295. * get_debug_info - fill a buffer with debugging information
  296. * @buffer: The buffer to be filled.
  297. * @count: The size of the buffer, in bytes.
  298. *
  299. * Fill a (usually PAGE_SIZEd) buffer with the debugging info that we will
  300. * either print log or return via sysfs.
  301. **/
  302. static int get_toi_debug_info(const char *buffer, int count)
  303. {
  304. int len = 0, i, first_result = 1;
  305. SNPRINTF("TuxOnIce debugging info:\n");
  306. SNPRINTF("- TuxOnIce core : " TOI_CORE_VERSION "\n");
  307. SNPRINTF("- Kernel Version : " UTS_RELEASE "\n");
  308. SNPRINTF("- Compiler vers. : %d.%d\n", __GNUC__, __GNUC_MINOR__);
  309. SNPRINTF("- Attempt number : %d\n", nr_hibernates);
  310. SNPRINTF("- Parameters : %ld %ld %ld %d %ld %ld\n",
  311. toi_result,
  312. toi_bkd.toi_action,
  313. toi_bkd.toi_debug_state,
  314. toi_bkd.toi_default_console_level,
  315. image_size_limit,
  316. toi_poweroff_method);
  317. SNPRINTF("- Overall expected compression percentage: %d.\n",
  318. 100 - toi_expected_compression_ratio());
  319. len += toi_print_module_debug_info(((char *)buffer) + len, count - len - 1);
  320. if (toi_bkd.toi_io_time[0][1]) {
  321. if ((io_MB_per_second(0) < 5) || (io_MB_per_second(1) < 5)) {
  322. SNPRINTF("- I/O speed: Write %ld KB/s",
  323. (KB((unsigned long)toi_bkd.toi_io_time[0][0]) * HZ /
  324. toi_bkd.toi_io_time[0][1]));
  325. if (toi_bkd.toi_io_time[1][1])
  326. SNPRINTF(", Read %ld KB/s", (KB((unsigned long)
  327. toi_bkd.toi_io_time[1][0]) * HZ /
  328. toi_bkd.toi_io_time[1][1]));
  329. } else {
  330. SNPRINTF("- I/O speed: Write %ld MB/s",
  331. (MB((unsigned long)toi_bkd.toi_io_time[0][0]) * HZ /
  332. toi_bkd.toi_io_time[0][1]));
  333. if (toi_bkd.toi_io_time[1][1])
  334. SNPRINTF(", Read %ld MB/s", (MB((unsigned long)
  335. toi_bkd.toi_io_time[1][0]) * HZ /
  336. toi_bkd.toi_io_time[1][1]));
  337. }
  338. SNPRINTF(".\n");
  339. } else
  340. SNPRINTF("- No I/O speed stats available.\n");
  341. SNPRINTF("- Extra pages : %lu used/%lu.\n",
  342. extra_pd1_pages_used, extra_pd1_pages_allowance);
  343. for (i = 0; i < min_t(int, TOI_NUM_RESULT_STATES, ARRAY_SIZE(result_strings)); i++)
  344. if (test_result_state(i)) {
  345. #ifdef CONFIG_TOI_FIXUP
  346. SNPRINTF("%s: %s.\n", first_result ?
  347. "- Result " : " ", result_strings[i]);
  348. #endif
  349. first_result = 0;
  350. }
  351. #ifdef CONFIG_TOI_FIXUP
  352. if (first_result)
  353. SNPRINTF("- Result : %s.\n", nr_hibernates ?
  354. "Succeeded" : "No hibernation attempts so far");
  355. #endif
  356. return len;
  357. }
  358. /**
  359. * do_cleanup - cleanup after attempting to hibernate or resume
  360. * @get_debug_info: Whether to allocate and return debugging info.
  361. *
  362. * Cleanup after attempting to hibernate or resume, possibly getting
  363. * debugging info as we do so.
  364. **/
  365. static void do_cleanup(int get_debug_info, int restarting)
  366. {
  367. int i = 0;
  368. char *buffer = NULL;
  369. trap_non_toi_io = 0;
  370. if (get_debug_info)
  371. toi_prepare_status(DONT_CLEAR_BAR, "Cleaning up...");
  372. #ifdef CONFIG_TOI_FIXUP
  373. #if !defined(HIB_TOI_DEBUG) /* turn off the verbose when debug off */
  374. hib_warn("Turn off debug info\n");
  375. get_debug_info = 0;
  376. #endif
  377. #endif
  378. #ifdef CONFIG_TOI_ENHANCE
  379. toi_actual_compression_ratio(); /* keep the actual compressed ratio for reference */
  380. #endif
  381. free_checksum_pages();
  382. if (get_debug_info)
  383. buffer = (char *)toi_get_zeroed_page(20, TOI_ATOMIC_GFP);
  384. if (buffer)
  385. i = get_toi_debug_info(buffer, PAGE_SIZE);
  386. toi_free_extra_pagedir_memory();
  387. pagedir1.size = 0;
  388. pagedir2.size = 0;
  389. set_highmem_size(pagedir1, 0);
  390. set_highmem_size(pagedir2, 0);
  391. if (boot_kernel_data_buffer) {
  392. if (!test_toi_state(TOI_BOOT_KERNEL))
  393. toi_free_page(37, boot_kernel_data_buffer);
  394. boot_kernel_data_buffer = 0;
  395. }
  396. if (test_toi_state(TOI_DEVICE_HOTPLUG_LOCKED)) {
  397. unlock_device_hotplug();
  398. clear_toi_state(TOI_DEVICE_HOTPLUG_LOCKED);
  399. }
  400. clear_toi_state(TOI_BOOT_KERNEL);
  401. if (current->flags & PF_SUSPEND_TASK)
  402. thaw_processes();
  403. if (!restarting)
  404. toi_stop_other_threads();
  405. if (test_action_state(TOI_KEEP_IMAGE) && !test_result_state(TOI_ABORTED)) {
  406. toi_message(TOI_ANY_SECTION, TOI_LOW, 1,
  407. "TuxOnIce: Not invalidating the image due to Keep Image being enabled.");
  408. set_result_state(TOI_KEPT_IMAGE);
  409. } else
  410. if (toiActiveAllocator)
  411. toiActiveAllocator->remove_image();
  412. free_bitmaps();
  413. usermodehelper_enable();
  414. if (test_toi_state(TOI_NOTIFIERS_PREPARE)) {
  415. pm_notifier_call_chain(PM_POST_HIBERNATION);
  416. clear_toi_state(TOI_NOTIFIERS_PREPARE);
  417. }
  418. if (buffer && i) {
  419. /* Printk can only handle 1023 bytes, including
  420. * its level mangling. */
  421. for (i = 0; i < 3; i++)
  422. pr_err("%s", buffer + (1023 * i));
  423. toi_free_page(20, (unsigned long)buffer);
  424. }
  425. if (!restarting)
  426. toi_cleanup_console();
  427. free_attention_list();
  428. if (!restarting)
  429. toi_deactivate_storage(0);
  430. clear_toi_state(TOI_IGNORE_LOGLEVEL);
  431. clear_toi_state(TOI_TRYING_TO_RESUME);
  432. clear_toi_state(TOI_NOW_RESUMING);
  433. }
  434. /**
  435. * check_still_keeping_image - we kept an image; check whether to reuse it.
  436. *
  437. * We enter this routine when we have kept an image. If the user has said they
  438. * want to still keep it, all we need to do is powerdown. If powering down
  439. * means hibernating to ram and the power doesn't run out, we'll return 1.
  440. * If we do power off properly or the battery runs out, we'll resume via the
  441. * normal paths.
  442. *
  443. * If the user has said they want to remove the previously kept image, we
  444. * remove it, and return 0. We'll then store a new image.
  445. **/
  446. static int check_still_keeping_image(void)
  447. {
  448. if (test_action_state(TOI_KEEP_IMAGE)) {
  449. pr_warn("Image already stored: powering down " "immediately.");
  450. do_toi_step(STEP_HIBERNATE_POWERDOWN);
  451. return 1; /* Just in case we're using S3 */
  452. }
  453. pr_warn("Invalidating previous image.\n");
  454. toiActiveAllocator->remove_image();
  455. return 0;
  456. }
  457. /**
  458. * toi_init - prepare to hibernate to disk
  459. *
  460. * Initialise variables & data structures, in preparation for
  461. * hibernating to disk.
  462. **/
  463. static int toi_init(int restarting)
  464. {
  465. int result, i, j;
  466. #ifdef CONFIG_TOI_FIXUP
  467. if (test_result_state(TOI_ABORTED))
  468. return 1;
  469. #endif
  470. toi_result = 0;
  471. pr_warn("Initiating a hibernation cycle.\n");
  472. nr_hibernates++;
  473. for (i = 0; i < 2; i++)
  474. for (j = 0; j < 2; j++)
  475. toi_bkd.toi_io_time[i][j] = 0;
  476. if (!test_toi_state(TOI_CAN_HIBERNATE) || allocate_bitmaps())
  477. return 1;
  478. mark_nosave_pages();
  479. if (!restarting)
  480. toi_prepare_console();
  481. result = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
  482. if (result) {
  483. set_result_state(TOI_NOTIFIERS_PREPARE_FAILED);
  484. return 1;
  485. }
  486. set_toi_state(TOI_NOTIFIERS_PREPARE);
  487. if (!restarting) {
  488. #ifdef CONFIG_TOI_FIXUP
  489. int num_threaded;
  490. num_threaded = toi_start_other_threads();
  491. pr_err("Starting other threads (%d).", num_threaded);
  492. #else
  493. pr_err("Starting other threads.");
  494. toi_start_other_threads();
  495. #endif
  496. }
  497. result = usermodehelper_disable();
  498. if (result) {
  499. pr_err("TuxOnIce: Failed to disable usermode " "helpers\n");
  500. set_result_state(TOI_USERMODE_HELPERS_ERR);
  501. return 1;
  502. }
  503. boot_kernel_data_buffer = toi_get_zeroed_page(37, TOI_ATOMIC_GFP);
  504. if (!boot_kernel_data_buffer) {
  505. pr_err("TuxOnIce: Failed to allocate " "boot_kernel_data_buffer.\n");
  506. set_result_state(TOI_OUT_OF_MEMORY);
  507. return 1;
  508. }
  509. return 0;
  510. }
  511. /**
  512. * can_hibernate - perform basic 'Can we hibernate?' tests
  513. *
  514. * Perform basic tests that must pass if we're going to be able to hibernate:
  515. * Can we get the pm_mutex? Is resume= valid (we need to know where to write
  516. * the image header).
  517. **/
  518. static int can_hibernate(void)
  519. {
  520. if (!test_toi_state(TOI_CAN_HIBERNATE))
  521. toi_attempt_to_parse_resume_device(0);
  522. if (!test_toi_state(TOI_CAN_HIBERNATE)) {
  523. pr_warn("TuxOnIce: Hibernation disabled. maybe no resume=swap:/dev/hda1 in lilo.conf or equivalent.");
  524. set_abort_result(TOI_CANT_SUSPEND);
  525. return 0;
  526. }
  527. if (strlen(alt_resume_param)) {
  528. attempt_to_parse_alt_resume_param();
  529. if (!strlen(alt_resume_param)) {
  530. pr_warn("Alternate resume parameter now " "invalid. Aborting.\n");
  531. set_abort_result(TOI_CANT_USE_ALT_RESUME);
  532. return 0;
  533. }
  534. }
  535. hib_log("passed!\n");
  536. return 1;
  537. }
  538. /**
  539. * do_post_image_write - having written an image, figure out what to do next
  540. *
  541. * After writing an image, we might load an alternate image or power down.
  542. * Powering down might involve hibernating to ram, in which case we also
  543. * need to handle reloading pageset2.
  544. **/
  545. static int do_post_image_write(void)
  546. {
  547. /* If switching images fails, do normal powerdown */
  548. if (alt_resume_param[0])
  549. do_toi_step(STEP_RESUME_ALT_IMAGE);
  550. toi_power_down();
  551. barrier();
  552. mb();
  553. return 0;
  554. }
  555. /**
  556. * __save_image - do the hard work of saving the image
  557. *
  558. * High level routine for getting the image saved. The key assumptions made
  559. * are that processes have been frozen and sufficient memory is available.
  560. *
  561. * We also exit through here at resume time, coming back from toi_hibernate
  562. * after the atomic restore. This is the reason for the toi_in_hibernate
  563. * test.
  564. **/
  565. static int __save_image(void)
  566. {
  567. int temp_result, did_copy = 0;
  568. toi_prepare_status(DONT_CLEAR_BAR, "Starting to save the image..");
  569. toi_message(TOI_ANY_SECTION, TOI_LOW, 1,
  570. " - Final values: %lu and %lu.", pagedir1.size, pagedir2.size);
  571. toi_cond_pause(1, "About to write pagedir2.");
  572. temp_result = write_pageset(&pagedir2);
  573. if (temp_result == -1 || test_result_state(TOI_ABORTED))
  574. return 1;
  575. toi_cond_pause(1, "About to copy pageset 1.");
  576. if (test_result_state(TOI_ABORTED))
  577. return 1;
  578. toi_deactivate_storage(1);
  579. toi_prepare_status(DONT_CLEAR_BAR, "Doing atomic copy/restore.");
  580. toi_in_hibernate = 1;
  581. if (toi_go_atomic(PMSG_FREEZE, 1))
  582. goto Failed;
  583. hib_log("calling toi_hibernate()\n");
  584. temp_result = toi_hibernate();
  585. #ifdef CONFIG_KGDB
  586. if (test_action_state(TOI_POST_RESUME_BREAKPOINT))
  587. kgdb_breakpoint();
  588. #endif
  589. if (!temp_result)
  590. did_copy = 1;
  591. hib_log("calling toi_end_atomic() toi_in_hibernate(%d) temp_result(%d)\n", toi_in_hibernate,
  592. temp_result);
  593. /* We return here at resume time too! */
  594. toi_end_atomic(ATOMIC_ALL_STEPS, toi_in_hibernate, temp_result);
  595. Failed:
  596. if (toi_activate_storage(1))
  597. panic("Failed to reactivate our storage.");
  598. /* Resume time? */
  599. if (!toi_in_hibernate) {
  600. hib_log("last resume here ...\n");
  601. copyback_post();
  602. return 0;
  603. }
  604. /* Nope. Hibernating. So, see if we can save the image... */
  605. if (temp_result || test_result_state(TOI_ABORTED)) {
  606. if (did_copy)
  607. goto abort_reloading_pagedir_two;
  608. else
  609. return 1;
  610. }
  611. hib_log("@line:%d\n", __LINE__);
  612. toi_update_status(pagedir2.size, pagedir1.size + pagedir2.size, NULL);
  613. if (test_result_state(TOI_ABORTED))
  614. goto abort_reloading_pagedir_two;
  615. toi_cond_pause(1, "About to write pageset1.");
  616. toi_message(TOI_ANY_SECTION, TOI_LOW, 1, "-- Writing pageset1");
  617. temp_result = write_pageset(&pagedir1);
  618. /* We didn't overwrite any memory, so no reread needs to be done. */
  619. if (test_action_state(TOI_TEST_FILTER_SPEED) || test_action_state(TOI_TEST_BIO))
  620. return 1;
  621. if (temp_result == 1 || test_result_state(TOI_ABORTED))
  622. goto abort_reloading_pagedir_two;
  623. toi_cond_pause(1, "About to write header.");
  624. if (test_result_state(TOI_ABORTED))
  625. goto abort_reloading_pagedir_two;
  626. temp_result = write_image_header();
  627. if (!temp_result && !test_result_state(TOI_ABORTED))
  628. return 0;
  629. abort_reloading_pagedir_two:
  630. temp_result = read_pageset2(1);
  631. /* If that failed, we're sunk. Panic! */
  632. if (temp_result)
  633. panic("Attempt to reload pagedir 2 while aborting " "a hibernate failed.");
  634. hib_log("passed!\n");
  635. return 1;
  636. }
  637. static void map_ps2_pages(int enable)
  638. {
  639. unsigned long pfn = 0;
  640. memory_bm_position_reset(pageset2_map);
  641. pfn = memory_bm_next_pfn(pageset2_map, 0);
  642. while (pfn != BM_END_OF_MAP) {
  643. struct page *page = pfn_to_page(pfn);
  644. kernel_map_pages(page, 1, enable);
  645. pfn = memory_bm_next_pfn(pageset2_map, 0);
  646. }
  647. }
  648. /**
  649. * do_save_image - save the image and handle the result
  650. *
  651. * Save the prepared image. If we fail or we're in the path returning
  652. * from the atomic restore, cleanup.
  653. **/
  654. static int do_save_image(void)
  655. {
  656. int result;
  657. map_ps2_pages(0);
  658. result = __save_image();
  659. map_ps2_pages(1);
  660. return result;
  661. }
  662. /**
  663. * do_prepare_image - try to prepare an image
  664. *
  665. * Seek to initialise and prepare an image to be saved. On failure,
  666. * cleanup.
  667. **/
  668. static int do_prepare_image(void)
  669. {
  670. int restarting = test_result_state(TOI_EXTRA_PAGES_ALLOW_TOO_SMALL);
  671. if (!restarting && toi_activate_storage(0))
  672. return 1;
  673. hib_log("step 1 @line:%d\n", __LINE__);
  674. /*
  675. * If kept image and still keeping image and hibernating to RAM, we will
  676. * return 1 after hibernating and resuming (provided the power doesn't
  677. * run out. In that case, we skip directly to cleaning up and exiting.
  678. */
  679. if (!can_hibernate() || (test_result_state(TOI_KEPT_IMAGE) && check_still_keeping_image()))
  680. return 1;
  681. hib_log("step 2 @line:%d\n", __LINE__);
  682. if (toi_init(restarting) || toi_prepare_image() || test_result_state(TOI_ABORTED))
  683. return 1;
  684. hib_log("step 3 @line:%d\n", __LINE__);
  685. trap_non_toi_io = 1;
  686. return 0;
  687. }
  688. /**
  689. * do_check_can_resume - find out whether an image has been stored
  690. *
  691. * Read whether an image exists. We use the same routine as the
  692. * image_exists sysfs entry, and just look to see whether the
  693. * first character in the resulting buffer is a '1'.
  694. **/
  695. int do_check_can_resume(void)
  696. {
  697. int result = -1;
  698. if (toi_activate_storage(0))
  699. return -1;
  700. if (!test_toi_state(TOI_RESUME_DEVICE_OK))
  701. toi_attempt_to_parse_resume_device(1);
  702. if (toiActiveAllocator)
  703. result = toiActiveAllocator->image_exists(1);
  704. toi_deactivate_storage(0);
  705. return result;
  706. }
  707. EXPORT_SYMBOL_GPL(do_check_can_resume);
  708. /**
  709. * do_load_atomic_copy - load the first part of an image, if it exists
  710. *
  711. * Check whether we have an image. If one exists, do sanity checking
  712. * (possibly invalidating the image or even rebooting if the user
  713. * requests that) before loading it into memory in preparation for the
  714. * atomic restore.
  715. *
  716. * If and only if we have an image loaded and ready to restore, we return 1.
  717. **/
  718. static int do_load_atomic_copy(void)
  719. {
  720. int read_image_result = 0;
  721. if (sizeof(swp_entry_t) != sizeof(long)) {
  722. pr_warn("TuxOnIce: The size of swp_entry_t != size of long. Please report this!");
  723. return 1;
  724. }
  725. if (!resume_file[0])
  726. pr_warn("TuxOnIce: use resume= command line parameter to tell TuxOnIce where to look for an image");
  727. toi_activate_storage(0);
  728. if (!(test_toi_state(TOI_RESUME_DEVICE_OK)) && !toi_attempt_to_parse_resume_device(0)) {
  729. /*
  730. * Without a usable storage device we can do nothing -
  731. * even if noresume is given
  732. */
  733. pr_err("TuxOnIce: No/wrong storage allocators : %d", toiNumAllocators);
  734. toi_deactivate_storage(0);
  735. return 1;
  736. }
  737. if (allocate_bitmaps())
  738. return 1;
  739. read_image_result = read_pageset1(); /* non fatal error ignored */
  740. if (test_toi_state(TOI_NORESUME_SPECIFIED))
  741. clear_toi_state(TOI_NORESUME_SPECIFIED);
  742. toi_deactivate_storage(0);
  743. if (read_image_result)
  744. return 1;
  745. return 0;
  746. }
  747. /**
  748. * prepare_restore_load_alt_image - save & restore alt image variables
  749. *
  750. * Save and restore the pageset1 maps, when loading an alternate image.
  751. **/
  752. static void prepare_restore_load_alt_image(int prepare)
  753. {
  754. static struct memory_bitmap *pageset1_map_save, *pageset1_copy_map_save;
  755. if (prepare) {
  756. pageset1_map_save = pageset1_map;
  757. pageset1_map = NULL;
  758. pageset1_copy_map_save = pageset1_copy_map;
  759. pageset1_copy_map = NULL;
  760. set_toi_state(TOI_LOADING_ALT_IMAGE);
  761. toi_reset_alt_image_pageset2_pfn();
  762. } else {
  763. toi_free_bitmap(&pageset1_map);
  764. pageset1_map = pageset1_map_save;
  765. toi_free_bitmap(&pageset1_copy_map);
  766. pageset1_copy_map = pageset1_copy_map_save;
  767. clear_toi_state(TOI_NOW_RESUMING);
  768. clear_toi_state(TOI_LOADING_ALT_IMAGE);
  769. }
  770. }
  771. /**
  772. * do_toi_step - perform a step in hibernating or resuming
  773. *
  774. * Perform a step in hibernating or resuming an image. This abstraction
  775. * is in preparation for implementing cluster support, and perhaps replacing
  776. * uswsusp too (haven't looked whether that's possible yet).
  777. **/
  778. int do_toi_step(int step)
  779. {
  780. switch (step) {
  781. case STEP_HIBERNATE_PREPARE_IMAGE:
  782. return do_prepare_image();
  783. case STEP_HIBERNATE_SAVE_IMAGE:
  784. return do_save_image();
  785. case STEP_HIBERNATE_POWERDOWN:
  786. return do_post_image_write();
  787. case STEP_RESUME_CAN_RESUME:
  788. return do_check_can_resume();
  789. case STEP_RESUME_LOAD_PS1:
  790. return do_load_atomic_copy();
  791. case STEP_RESUME_DO_RESTORE:
  792. /*
  793. * If we succeed, this doesn't return.
  794. * Instead, we return from do_save_image() in the
  795. * hibernated kernel.
  796. */
  797. return toi_atomic_restore();
  798. case STEP_RESUME_ALT_IMAGE:
  799. pr_warn("Trying to resume alternate image.\n");
  800. toi_in_hibernate = 0;
  801. save_restore_alt_param(SAVE, NOQUIET);
  802. prepare_restore_load_alt_image(1);
  803. if (!do_check_can_resume()) {
  804. pr_warn("Nothing to resume from.\n");
  805. goto out;
  806. }
  807. if (!do_load_atomic_copy())
  808. toi_atomic_restore();
  809. pr_warn("Failed to load image.\n");
  810. out:
  811. prepare_restore_load_alt_image(0);
  812. save_restore_alt_param(RESTORE, NOQUIET);
  813. break;
  814. case STEP_CLEANUP:
  815. do_cleanup(1, 0);
  816. break;
  817. case STEP_QUIET_CLEANUP:
  818. do_cleanup(0, 0);
  819. break;
  820. }
  821. return 0;
  822. }
  823. EXPORT_SYMBOL_GPL(do_toi_step);
  824. /* -- Functions for kickstarting a hibernate or resume --- */
  825. /**
  826. * toi_try_resume - try to do the steps in resuming
  827. *
  828. * Check if we have an image and if so try to resume. Clear the status
  829. * flags too.
  830. **/
  831. void toi_try_resume(void)
  832. {
  833. #ifdef CONFIG_TOI_FIXUP
  834. int num_threaded;
  835. #endif
  836. hib_log("entering...\n");
  837. set_toi_state(TOI_TRYING_TO_RESUME);
  838. resume_attempted = 1;
  839. current->flags |= PF_MEMALLOC;
  840. #ifdef CONFIG_TOI_FIXUP
  841. get_online_cpus(); /* to protect against hotplug interference */
  842. num_threaded = toi_start_other_threads();
  843. pr_err("[resume] Starting other threads (%d).", num_threaded);
  844. if (do_toi_step(STEP_RESUME_CAN_RESUME) && !do_toi_step(STEP_RESUME_LOAD_PS1)) {
  845. put_online_cpus(); /* to protect against hotplug interference */
  846. do_toi_step(STEP_RESUME_DO_RESTORE);
  847. } else {
  848. put_online_cpus(); /* to protect against hotplug interference */
  849. }
  850. #else
  851. toi_start_other_threads();
  852. if (do_toi_step(STEP_RESUME_CAN_RESUME) && !do_toi_step(STEP_RESUME_LOAD_PS1))
  853. do_toi_step(STEP_RESUME_DO_RESTORE);
  854. #endif
  855. toi_stop_other_threads();
  856. do_cleanup(0, 0);
  857. current->flags &= ~PF_MEMALLOC;
  858. clear_toi_state(TOI_IGNORE_LOGLEVEL);
  859. clear_toi_state(TOI_TRYING_TO_RESUME);
  860. clear_toi_state(TOI_NOW_RESUMING);
  861. }
  862. /**
  863. * toi_sys_power_disk_try_resume - wrapper calling toi_try_resume
  864. *
  865. * Wrapper for when __toi_try_resume is called from swsusp resume path,
  866. * rather than from echo > /sys/power/tuxonice/do_resume.
  867. **/
  868. static void toi_sys_power_disk_try_resume(void)
  869. {
  870. resume_attempted = 1;
  871. hib_log("step 1 @line:%d\n", __LINE__);
  872. /*
  873. * There's a comment in kernel/power/disk.c that indicates
  874. * we should be able to use mutex_lock_nested below. That
  875. * doesn't seem to cut it, though, so let's just turn lockdep
  876. * off for now.
  877. */
  878. lockdep_off();
  879. if (toi_start_anything(SYSFS_RESUMING))
  880. goto out;
  881. toi_try_resume();
  882. /*
  883. * For initramfs, we have to clear the boot time
  884. * flag after trying to resume
  885. */
  886. clear_toi_state(TOI_BOOT_TIME);
  887. toi_finish_anything(SYSFS_RESUMING);
  888. out:
  889. lockdep_on();
  890. }
  891. /**
  892. * toi_try_hibernate - try to start a hibernation cycle
  893. *
  894. * Start a hibernation cycle, coming in from either
  895. * echo > /sys/power/tuxonice/do_suspend
  896. *
  897. * or
  898. *
  899. * echo disk > /sys/power/state
  900. *
  901. * In the later case, we come in without pm_sem taken; in the
  902. * former, it has been taken.
  903. **/
  904. int toi_try_hibernate(void)
  905. {
  906. int result = 0, sys_power_disk = 0, retries = 0;
  907. if (!mutex_is_locked(&tuxonice_in_use)) {
  908. /* Came in via /sys/power/disk */
  909. if (toi_start_anything(SYSFS_HIBERNATING))
  910. return -EBUSY;
  911. sys_power_disk = 1;
  912. }
  913. current->flags |= PF_MEMALLOC;
  914. if (test_toi_state(TOI_CLUSTER_MODE)) {
  915. toi_initiate_cluster_hibernate();
  916. goto out;
  917. }
  918. prepare:
  919. result = do_toi_step(STEP_HIBERNATE_PREPARE_IMAGE);
  920. hib_log("after calling do_toi_step(STEP_HIBERNATE_PREPARE_IMAGE), result(%d)\n", result);
  921. if (result)
  922. goto out;
  923. if (test_action_state(TOI_FREEZER_TEST))
  924. goto out_restore_gfp_mask;
  925. result = do_toi_step(STEP_HIBERNATE_SAVE_IMAGE);
  926. if (test_result_state(TOI_EXTRA_PAGES_ALLOW_TOO_SMALL)) {
  927. if (retries < 2) {
  928. hib_log("failed and calling do_cleanup(0, 1)\n");
  929. do_cleanup(0, 1);
  930. retries++;
  931. clear_result_state(TOI_ABORTED);
  932. extra_pd1_pages_allowance = extra_pd1_pages_used + 500;
  933. pr_warn("Automatically adjusting the extra pages allowance to %ld and restarting",
  934. extra_pd1_pages_allowance);
  935. pm_restore_gfp_mask();
  936. goto prepare;
  937. }
  938. pr_warn("Adjusted extra pages allowance twice and still couldn't hibernate successfully. Giving up.");
  939. }
  940. /* This code runs at resume time too! */
  941. if (!result && toi_in_hibernate)
  942. result = do_toi_step(STEP_HIBERNATE_POWERDOWN);
  943. out_restore_gfp_mask:
  944. pm_restore_gfp_mask();
  945. out:
  946. do_cleanup(1, 0);
  947. current->flags &= ~PF_MEMALLOC;
  948. if (sys_power_disk)
  949. toi_finish_anything(SYSFS_HIBERNATING);
  950. return result;
  951. }
  952. /*
  953. * channel_no: If !0, -c <channel_no> is added to args (userui).
  954. */
  955. int toi_launch_userspace_program(char *command, int channel_no, int wait, int debug)
  956. {
  957. int retval;
  958. static char *envp[4] = {
  959. "HOME=/",
  960. "TERM=linux",
  961. "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
  962. NULL
  963. };
  964. char *argv[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  965. };
  966. char *channel = NULL;
  967. int arg = 0, size;
  968. char test_read[255];
  969. char *orig_posn = command;
  970. if (!strlen(orig_posn))
  971. return 1;
  972. if (channel_no) {
  973. channel = toi_kzalloc(4, 6, GFP_KERNEL);
  974. if (!channel) {
  975. pr_warn("Failed to allocate memory in preparing to launch userspace program.");
  976. return 1;
  977. }
  978. }
  979. /* Up to 6 args supported */
  980. while (arg < 6) {
  981. if (sscanf(orig_posn, "%254s", test_read) != 1) {
  982. pr_warn("Failed to sscanf from userspace program command");
  983. break;
  984. }
  985. size = strlen(test_read);
  986. if (!(size))
  987. break;
  988. argv[arg] = toi_kzalloc(5, size + 1, TOI_ATOMIC_GFP);
  989. strcpy(argv[arg], test_read);
  990. orig_posn += size + 1;
  991. *test_read = 0;
  992. arg++;
  993. }
  994. if (channel_no) {
  995. sprintf(channel, "-c%d", channel_no);
  996. argv[arg] = channel;
  997. } else
  998. arg--;
  999. if (debug) {
  1000. argv[++arg] = toi_kzalloc(5, 8, TOI_ATOMIC_GFP);
  1001. strcpy(argv[arg], "--debug");
  1002. }
  1003. retval = call_usermodehelper(argv[0], argv, envp, wait);
  1004. /*
  1005. * If the program reports an error, retval = 256. Don't complain
  1006. * about that here.
  1007. */
  1008. if (retval && retval != 256)
  1009. pr_err("Failed to launch userspace program '%s': Error %d\n", command, retval);
  1010. {
  1011. int i;
  1012. for (i = 0; i < arg; i++)
  1013. if (argv[i] && argv[i] != channel)
  1014. toi_kfree(5, argv[i], sizeof(*argv[i]));
  1015. }
  1016. toi_kfree(4, channel, sizeof(*channel));
  1017. return retval;
  1018. }
  1019. #ifdef CONFIG_TOI_ENHANCE
  1020. int toi_abort_hibernate(void)
  1021. {
  1022. if (test_result_state(TOI_ABORTED))
  1023. return 0;
  1024. set_result_state(TOI_ABORTED);
  1025. return 0;
  1026. }
  1027. EXPORT_SYMBOL_GPL(toi_abort_hibernate);
  1028. int toi_hibernate_fatalerror(void)
  1029. {
  1030. if (test_result_state(TOI_ARCH_PREPARE_FAILED))
  1031. return 1;
  1032. else
  1033. return 0;
  1034. }
  1035. EXPORT_SYMBOL_GPL(toi_hibernate_fatalerror);
  1036. #endif
  1037. /*
  1038. * This array contains entries that are automatically registered at
  1039. * boot. Modules and the console code register their own entries separately.
  1040. */
  1041. static struct toi_sysfs_data sysfs_params[] = {
  1042. SYSFS_LONG("extra_pages_allowance", SYSFS_RW,
  1043. &extra_pd1_pages_allowance, 0, LONG_MAX, 0),
  1044. SYSFS_CUSTOM("image_exists", SYSFS_RW, image_exists_read,
  1045. image_exists_write, SYSFS_NEEDS_SM_FOR_BOTH, NULL),
  1046. SYSFS_STRING("resume", SYSFS_RW, resume_file, 255,
  1047. SYSFS_NEEDS_SM_FOR_WRITE,
  1048. attempt_to_parse_resume_device2),
  1049. SYSFS_STRING("alt_resume_param", SYSFS_RW, alt_resume_param, 255,
  1050. SYSFS_NEEDS_SM_FOR_WRITE,
  1051. attempt_to_parse_alt_resume_param),
  1052. SYSFS_CUSTOM("debug_info", SYSFS_READONLY, get_toi_debug_info, NULL, 0,
  1053. NULL),
  1054. SYSFS_BIT("ignore_rootfs", SYSFS_RW, &toi_bkd.toi_action,
  1055. TOI_IGNORE_ROOTFS, 0),
  1056. SYSFS_LONG("image_size_limit", SYSFS_RW, &image_size_limit, -2,
  1057. INT_MAX, 0),
  1058. SYSFS_UL("last_result", SYSFS_RW, &toi_result, 0, 0, 0),
  1059. SYSFS_BIT("no_multithreaded_io", SYSFS_RW, &toi_bkd.toi_action,
  1060. TOI_NO_MULTITHREADED_IO, 0),
  1061. SYSFS_BIT("no_flusher_thread", SYSFS_RW, &toi_bkd.toi_action,
  1062. TOI_NO_FLUSHER_THREAD, 0),
  1063. SYSFS_BIT("full_pageset2", SYSFS_RW, &toi_bkd.toi_action,
  1064. TOI_PAGESET2_FULL, 0),
  1065. SYSFS_BIT("reboot", SYSFS_RW, &toi_bkd.toi_action, TOI_REBOOT, 0),
  1066. SYSFS_BIT("replace_swsusp", SYSFS_RW, &toi_bkd.toi_action,
  1067. TOI_REPLACE_SWSUSP, 0),
  1068. SYSFS_STRING("resume_commandline", SYSFS_RW,
  1069. toi_bkd.toi_nosave_commandline, COMMAND_LINE_SIZE, 0,
  1070. NULL),
  1071. SYSFS_STRING("version", SYSFS_READONLY, TOI_CORE_VERSION, 0, 0, NULL),
  1072. SYSFS_BIT("freezer_test", SYSFS_RW, &toi_bkd.toi_action,
  1073. TOI_FREEZER_TEST, 0),
  1074. SYSFS_BIT("test_bio", SYSFS_RW, &toi_bkd.toi_action, TOI_TEST_BIO, 0),
  1075. SYSFS_BIT("test_filter_speed", SYSFS_RW, &toi_bkd.toi_action,
  1076. TOI_TEST_FILTER_SPEED, 0),
  1077. SYSFS_BIT("no_pageset2", SYSFS_RW, &toi_bkd.toi_action,
  1078. TOI_NO_PAGESET2, 0),
  1079. SYSFS_BIT("no_pageset2_if_unneeded", SYSFS_RW, &toi_bkd.toi_action,
  1080. TOI_NO_PS2_IF_UNNEEDED, 0),
  1081. SYSFS_STRING("binary_signature", SYSFS_READONLY,
  1082. tuxonice_signature, 9, 0, NULL),
  1083. SYSFS_INT("max_workers", SYSFS_RW, &toi_max_workers, 0, nr_cpumask_bits, 0,
  1084. NULL),
  1085. #ifdef CONFIG_KGDB
  1086. SYSFS_BIT("post_resume_breakpoint", SYSFS_RW, &toi_bkd.toi_action,
  1087. TOI_POST_RESUME_BREAKPOINT, 0),
  1088. #endif
  1089. SYSFS_BIT("no_readahead", SYSFS_RW, &toi_bkd.toi_action,
  1090. TOI_NO_READAHEAD, 0),
  1091. SYSFS_BIT("trace_debug_on", SYSFS_RW, &toi_bkd.toi_action,
  1092. TOI_TRACE_DEBUG_ON, 0),
  1093. #ifdef CONFIG_TOI_KEEP_IMAGE
  1094. SYSFS_BIT("keep_image", SYSFS_RW, &toi_bkd.toi_action, TOI_KEEP_IMAGE,
  1095. 0),
  1096. #endif
  1097. };
  1098. static struct toi_core_fns my_fns = {
  1099. .get_nonconflicting_page = __toi_get_nonconflicting_page,
  1100. .post_context_save = __toi_post_context_save,
  1101. .try_hibernate = toi_try_hibernate,
  1102. .try_resume = toi_sys_power_disk_try_resume,
  1103. };
  1104. /**
  1105. * core_load - initialisation of TuxOnIce core
  1106. *
  1107. * Initialise the core, beginning with sysfs. Checksum and so on are part of
  1108. * the core, but have their own initialisation routines because they either
  1109. * aren't compiled in all the time or have their own subdirectories.
  1110. **/
  1111. static __init int core_load(void)
  1112. {
  1113. int i, numfiles = sizeof(sysfs_params) / sizeof(struct toi_sysfs_data);
  1114. pr_warn("TuxOnIce " TOI_CORE_VERSION " (http://tuxonice.net)\n");
  1115. if (!hibernation_available()) {
  1116. pr_warn("TuxOnIce disabled due to request for hibernation to be disabled in this kernel");
  1117. return 1;
  1118. }
  1119. if (toi_sysfs_init())
  1120. return 1;
  1121. for (i = 0; i < numfiles; i++)
  1122. toi_register_sysfs_file(tuxonice_kobj, &sysfs_params[i]);
  1123. toi_core_fns = &my_fns;
  1124. if (toi_alloc_init())
  1125. return 1;
  1126. if (toi_checksum_init())
  1127. return 1;
  1128. if (toi_usm_init())
  1129. return 1;
  1130. if (toi_ui_init())
  1131. return 1;
  1132. if (toi_poweroff_init())
  1133. return 1;
  1134. if (toi_cluster_init())
  1135. return 1;
  1136. return 0;
  1137. }
  1138. #ifdef MODULE
  1139. /**
  1140. * core_unload: Prepare to unload the core code.
  1141. **/
  1142. static __exit void core_unload(void)
  1143. {
  1144. int i, numfiles = sizeof(sysfs_params) / sizeof(struct toi_sysfs_data);
  1145. toi_alloc_exit();
  1146. toi_checksum_exit();
  1147. toi_poweroff_exit();
  1148. toi_ui_exit();
  1149. toi_usm_exit();
  1150. toi_cluster_exit();
  1151. for (i = 0; i < numfiles; i++)
  1152. toi_unregister_sysfs_file(tuxonice_kobj, &sysfs_params[i]);
  1153. toi_core_fns = NULL;
  1154. toi_sysfs_exit();
  1155. }
  1156. MODULE_LICENSE("GPL");
  1157. module_init(core_load);
  1158. module_exit(core_unload);
  1159. #else
  1160. late_initcall(core_load);
  1161. #endif